Geometry shader总结

什么是Geometry Shader

GS存在于vertext shader和固定功能vertex post-processing stage之间,它是可选的不是必要的。
GS的输入是单个primitive,输出可能是0个或多个primitive.

GS的作用

GS的主要作用就是从已有的primitive中生成新的primitive,它可以“无中生有”的生成新的顶点

OpenGL官网上提到两种用法:

Layered rendering: 对一个primitive,不改变rendertarget渲染出多个图片
  Transform Feedback: 用来执行GPU的计算任务(pre-compute shader)

下图是个例子,给GS输入一个三角形,GS输出4个三角形

Layered Rendering

上面说到了,GS的一大用处体现在layerd rendering,即多层渲染。

试想一下,对于多层纹理而言,每一层的纹理坐标实际上是相同的。层号如何指定呢?固然可以在建立VBO时给纹理坐标第三个维度值,但是这并不会让OpenGL画到你想画的层上:Fragment的过程就是将顶点像素化的过程,而这个过程是二维的……最后拿到的二维图像必然没有深度,层数无从谈起。

但是Geometry却有个关键的内建输出变量:out int gl_Layer,正是它能够指定绘制的层数。我们不妨先将我写出来的geometry shader的内容贴出来,注意显卡至少要支持到OpenGL 4.0,#version这句至少是400:

 1 #version 450
 2 layout (triangles, invocations = 2) in; //输入三角形,2次调用
 3 layout (triangle_strip, max_vertices = 3) out;  //输出三角形
 4 in vec2 gTexCoord[];    //从Vertex传过来的纹理坐标
 5 out vec2 fTexCoord;     //传到Fragment去的纹理坐标
 6 out int gl_Layer;   //层数的标记
 7 void main()
 8 {
 9     for(int k=0; k<gl_in.length(); k++)   //针对三角形每个顶点
10     {
11         gl_Layer = gl_InvocationID;    //用调用编号标记层号
12         fTexCoord = gTexCoord[k];    //纹理坐标传递
13         gl_Position = gl_in[k].gl_Position;    //顶点坐标传递
14         EmitVertex();    //开始传递顶点信息,对每个顶点调用一次
15     }
16     EndPrimitive();    //结束一个primitive,一个primitive调用一次
17 }

需要注意的是,triangles意味着你在OpenGL的绘制指令必须是GL_TRIANGLEGL_TRIANGLE_STRIP或者GL_TRIANGLE_FAN。其他的对应关系可以在Wiki查到。三角形有3个顶点,这一组3个顶点将同时进入Geometry中,因此在Geometry中能拿到一个gl_in[]的内建数组,这个数组的大小应该跟绘制时一组顶点的数量一致,三角形就是3。而在这里我不需要增加顶点,因此输出也还是3个顶点。同时纹理坐标也理所当然地变成了数组。因此需要一个循环来对三角形的每个顶点进行操作。

这里顶点坐标和纹理坐标都不必改,因此直接传递过去了。重点在于gl_Layer这一句。gl_Layer这个内建变量用于指示当前绘制的层号,这个值将影响像素化后像素绘制到哪一层上。OpenGL要求一组顶点(这里是一个三角形)内部的gl_Layer必须一致。这里赋值之后顺便把它传到Fragment里作为标志。
关键的一步在于第二行的invocations = 2gl_InvocationID这个内建变量。invocations=n指示Geometry对每组顶点做n次运算,用gl_InvocationID来标记每次运算的序号。我们可以将这个序号送到gl_Layer来作为层号的值!这样geometry就会将这一组顶点重复发送两次,而这两次是发送到不同层上的,从而实现不同层的绘制!

接下来只要在Fragment里拿到这个gl_Layer,根据需要分层作处理就可以了。

时间: 2024-10-16 09:46:11

Geometry shader总结的相关文章

Unity Geometry Shader实现

unity官方文档关于geometry shader的内容等同于没有,这也是因为unity的开发者基本面向的是移动平台开发,所以这种SM4.0的特性基本都不会被开发者考虑.但是本着与时俱进的精神(虽然现在已经不早了)还是研究一下以备不时之需. 在开始unity geometry shader之前,通过DX10的龙书,简单的了解了一下geometry shader的原理.然后看了一个GS的billboard例子,觉得大同小异. 首先要知道,GS和VS以及FS的区别. 在dx9的渲染管线中,可编程的

GLSL Core Tutorial &ndash; Geometry Shader

原文:http://www.lighthouse3d.com/tutorials/glsl-core-tutorial/geometry-shader/     几何shader是OpenGL3.2之后的内容.这个阶段是可选的,当使用时,它接受在上一阶段组合的图元作为输入.一个几何shader不接受条带状,伞状或者环状的图元.几何shader接受组合后的图元,所以如何绘制命令指明是三角形带图元的话,几何shader实际上接受的是三角形.     跟顶点shader比较,几何shader完全知道正

GLSL-几何着色器详解跟实例(GS:Geometry Shader)[转]

[OpenGL4.0]GLSL-几何着色器详解和实例(GS:Geometry Shader) 一.什么是几何着色器(GS:Geometry Shader) Input Assembler(IA)从顶点缓冲区上的输入流中接收顶点数据,并且把数据项转换为规范的格式.vertex shader通常用来把顶点从模型空间变换到平面空间,vertex shader读取一个顶点,输出一个顶点.Pixel Shader读取单一pixel属性,输出包含颜色和Z信息的的片断.而geometry shader是Dir

osg中使用geometry shader方式

可以参考osg示例代码osggeometryshaders 它用glsl版本比较老#version 120 #extension GL_EXT_geometry_shader4 : enable 使用gl_PositionIn[],而不能使用gl_in[],这个需要更高版本 类似以下代码: #version 150 layout(triangles) in; layout(triangle_strip, max_vertices=3) out;vec4 p0_3d = gl_in[0].gl_P

Unity3D Compute shader 新解粒子堆积矩阵【二】

Unity3D Compute shader 新解粒子堆积矩阵[二] 1.Compute Shader都出来了好些年了,幸好Unity3D 加入了该特性,当然U3D本着易开发操作平台,在u3d中实现compute shader起来是相当轻松的. 2.除了Compute Shader,还有 Vertex shader,Geometry shader,Fragment shader ; Tesselation shader,Domain shader,Hull Shader ,如果你觉得有一种都想学

dx11 入门 Tutorial 03: 什么是shader DirectXSampleBrowser(June 2010)

对shader的认知: shader是什么? In Direct3D 11, shaders reside in different stages of the graphics pipeline. They are short programs that, executed by the GPU, take certain input data, process that data, and then output the result to the next stage of the pip

基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)

在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时,我们还会介绍VBO(顶点缓冲区对象)和VAO(顶点数组对象)的基本用法. 在编写自己的shader之前,我觉得有必要提一下OpenGL渲染管线. 理解OpenGL渲染管线,对于学习OpenGL非常重要.下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段) 此图是从wiki中拿过来的

关于Shader的跨平台方案的考虑

Apple 推出 metal后,除了新的metal framewrok外,也多了一种新的shader语言,最近工作也做了一些metal移植的测试,主要还是现有引擎如何可以快速支持metal的解决方案.这里也想对边写写自己的心得. metal shader的语法特性更接近SM5的hlsl,所以sm4或sm5的hlsl转化成metal shader更简单,性能跟GLES3.1相似,提供了Vextrex shader, Fragment Shader和Computer Shader.加上移动端图形AP

着色器(Shader)

着色器(Shader) 顶点着色器(Vertex shader) 片段着色器(Fragment shader) 几何着色器(Geometry Shader) 提供通用计算能力的着色器(Compute Shader) 顶点着色器(Vertex Shader) 每个顶点都要执行一次Vertex Shader. 它的功能就是把每个顶点在虚拟空间中的三维坐标变换为可以在 屏幕上显示的二维坐标,并带有用于z-buffer的深度信息.可操作属性:位置.颜色.纹理坐标,但是不能创建新的顶点. 主要完成以下工作