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)
Real-time rendering书中提到了几种效果可以用GS来实现:
creating various sized particles from point data
extruding fins along silhouettes for fur rendering
finding object edges for shadow algorithms
下图是个例子,给GS输入一个三角形,GS输出4个三角形

Layered Rendering
上面说到了,GS的一大用处体现在layerd rendering,即多层渲染。
试想一下,对于多层纹理而言,每一层的纹理坐标实际上是相同的。层号如何指定呢?固然可以在建立VBO时给纹理坐标第三个维度值,但是这并不会让OpenGL画到你想画的层上:Fragment的过程就是将顶点像素化的过程,而这个过程是二维的……最后拿到的二维图像必然没有深度,层数无从谈起。
但是Geometry却有个关键的内建输出变量:out int gl_Layer,正是它能够指定绘制的层数。我们不妨先将我写出来的geometry shader的内容贴出来,注意显卡至少要支持到OpenGL 4.0,#version这句至少是400:
#version
layout (triangles, invocations = ) in; //输入三角形,2次调用
layout (triangle_strip, max_vertices = ) out; //输出三角形
in vec2 gTexCoord[]; //从Vertex传过来的纹理坐标
out vec2 fTexCoord; //传到Fragment去的纹理坐标
out int gl_Layer; //层数的标记
void main()
{
for(int k=; k<gl_in.length(); k++) //针对三角形每个顶点
{
gl_Layer = gl_InvocationID; //用调用编号标记层号
fTexCoord = gTexCoord[k]; //纹理坐标传递
gl_Position = gl_in[k].gl_Position; //顶点坐标传递
EmitVertex(); //开始传递顶点信息,对每个顶点调用一次
}
EndPrimitive(); //结束一个primitive,一个primitive调用一次
}
需要注意的是,triangles意味着你在OpenGL的绘制指令必须是GL_TRIANGLE、GL_TRIANGLE_STRIP或者GL_TRIANGLE_FAN。其他的对应关系可以在Wiki查到。三角形有3个顶点,这一组3个顶点将同时进入Geometry中,因此在Geometry中能拿到一个gl_in[]的内建数组,这个数组的大小应该跟绘制时一组顶点的数量一致,三角形就是3。而在这里我不需要增加顶点,因此输出也还是3个顶点。同时纹理坐标也理所当然地变成了数组。因此需要一个循环来对三角形的每个顶点进行操作。
这里顶点坐标和纹理坐标都不必改,因此直接传递过去了。重点在于gl_Layer这一句。gl_Layer这个内建变量用于指示当前绘制的层号,这个值将影响像素化后像素绘制到哪一层上。OpenGL要求一组顶点(这里是一个三角形)内部的gl_Layer必须一致。这里赋值之后顺便把它传到Fragment里作为标志。 
关键的一步在于第二行的invocations = 2和gl_InvocationID这个内建变量。invocations=n指示Geometry对每组顶点做n次运算,用gl_InvocationID来标记每次运算的序号。我们可以将这个序号送到gl_Layer来作为层号的值!这样geometry就会将这一组顶点重复发送两次,而这两次是发送到不同层上的,从而实现不同层的绘制!
接下来只要在Fragment里拿到这个gl_Layer,根据需要分层作处理就可以了。
用Transform feedback创建粒子系统
粒子系统是为了模仿一些自然现象(比如烟,灰尘,烟火,雨等)所使用的技术的一个通用名字。在这些现象中,共同的地方就是它们是由大量的小粒子所组成,这些小的粒子以某种方式在一起移动,这样就构成了一种自然现象。
DirectX10 介绍了一个新的特性叫 Stream Output,这个对于粒子系统的实现是非常有用的。OpenGL 在 3.0 
版本之后也加入了这个特性——Transform Feedback,其实现思路是在 GS(如果没有使用 GS 则是 
VS)处理之后,我们可以将变换之后的图元存放到一个特殊的缓存——Transform Feedback Buffer 
中。此外,我们可以决定图元是否将继续按照以前的流程进行光栅化。在下一帧渲染的时候,上一帧中输出的顶点信息可以在这一帧中作为顶点缓存使用,在这样的一个循环过程中,我们可以不借助于应用程序来实现对粒子信息的更新。下面这幅图片介绍了 Transform Feedback Buffer 在管线中所处的位置。

Geometry shader总结的更多相关文章
- CSharpGL(14)用geometry shader渲染模型的法线(normal)
		
+BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(14)用geometry shader渲染模型的法线(normal) +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 ...
 - GLSL-几何着色器详解跟实例(GS:Geometry Shader)[转]
		
[OpenGL4.0]GLSL-几何着色器详解和实例(GS:Geometry Shader) 一.什么是几何着色器(GS:Geometry Shader) Input Assembler(IA)从顶点 ...
 - Geometry Shader 【转】
		
Geometry shader – receives as its input complete primitives as a collection of vertices, and these i ...
 - OpenGL Geometry Shader
		
http://blog.csdn.net/bugrunner/article/details/5455324 Geometry Shader可以处理Vertex Shader和Fragment Sha ...
 - Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader)
		
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader) 代码工 ...
 - Geometry Shader 实现 Wireframe 绘制边线的Shader
		
最终效果: 参考了一个免费插件 https://assetstore.unity.com/packages/vfx/shaders/directx-11/ucla-wireframe-shader-2 ...
 - Unity Shader入门基础(一)
		
渲染流水线 一.渲染流水线 渲染流水线的工作任务在于由一个三维场景出发.生存(或者说渲染)一张二维图像.换句话说,计算机需要从一系列的顶点数据.纹理等信息出发,把这些信息最终转换成一张人眼可以看到 ...
 - Shader Model 版本与DirectX的关系(OpenGL对应的呢?)
		
http://blog.sina.com.cn/s/blog_6e521a600100q4dr.html DX9还是能支持到固定管线的,虽然说是在内部被转换成shader: DX10明确不再支持固定管 ...
 - 关于Shader的跨平台方案的考虑
		
Apple 推出 metal后,除了新的metal framewrok外,也多了一种新的shader语言,最近工作也做了一些metal移植的测试,主要还是现有引擎如何可以快速支持metal的解决方 ...
 
随机推荐
- javascript的this
			
关于JavaScript中的this的取值: 函数在创建的时候,会创建两个隐藏属性:函数的上下文.实现函数行为的代码(调用属性):以及prototype属性.length属性. 函数在调用的时候,除了 ...
 - int.Parse()、int.TryParse()和Convert.ToInt32()的区别
			
1:int.Parse(一个参数) 此参数必须满足: 1 只能是字符串: 2 只能是 “整型” 字符串,即各种整型ToString()之后的形式,也不能为浮点型. 2:int.TryPa ...
 - cellmap for iphone
			
说明:Cellmap的Iphone版本已经上架APP Store. 如需下载,可以登陆app store,然后搜索cellmap进行下载. 或者直接登陆以下地址下载: https://itunes.a ...
 - iso 培训笔记
			
protocol协议 + 类方法- 实例方法:继承()方法 <> [] 方法调用 .属性:参数mvc storyboard 资源文件info.plist 权限viewcontroller ...
 - QGC 支付宝无法异步通知及异步通知常见问题注意事项
			
支付宝异步通知参数(notify_url)路径常见问题注意事项: 1.不能是内网或者局域网地址,必须是外网可以访问的.否则无法调用!! 2.地址不能有session拦截,支付宝主动发送,所有sessi ...
 - SQL Server Analysis Services SSAS Processing Error Configurations
			
转载:https://www.mssqltips.com/sqlservertip/3476/sql-server-analysis-services-ssas-processing-error-co ...
 - linux 安装 python2.7
			
若新安装虚拟机,或者新装linux系统.需安装gcc等yum -y install gcc gcc-c++ autoconf automake cmake ntp rsync ssh vim yum ...
 - [Java] - Google API调用
			
由于Google已经完成被墙,要上Google必需使用代理或VPN. 这里使用的是Google的GoAgent代理做开发.(如何使用GoAgent,这里不写了,忽略500字.....) 本地测试的Go ...
 - 承接cardboard外包,unity3d外包(北京动软— 谷歌CARDBOARD真强大)
			
手把手教你玩转googlecardboard[不知道在这里发可以不?] 谷歌Google I/O开发者大会于北京时间6月26日0点在美国旧金山举行,谷歌发布了Android L手机系统:Android ...
 - linux中service *** start与直接运行/usr/bin/***的区别
			
在linux想要运行启动一个服务有两种方法: 1,运行/etc/init.d/目录下的shell脚本,还可以有快捷方式,service *** start/ stop/restart /status, ...