Chapter 3 – The Graphics Processing Unit

3.7 几何着色器(Geometry Shader)

几何着色器可以讲原先的图元转换为其他图元。例如,一个三角形网格可以被转换为一个线框。在2006年下半年,DX10面世,同时几何着色器也加入了硬件加速的图形管线中。其位于tessellation shader的后面,也是可选择的。但是只有在Shader Model 4.0后的版本才支持几何着色器。

几何着色器的输入是一个单一的物体与其相应的顶点。该物体一般由三角形组成,或者是一个线段,或者只是一个点。几何着色器负责将图元进行延伸并处理。此外,我们可以为每个三角形添加三个外部的定点,也可以为每个线段添加两个相邻的定点。随着DX11与Shader Model 5.0的推出,我们可以传入更复杂的patch,最多支持32个控制点。也就是说,tessellation阶段能够更高效地生成patch。

几何着色器回处理这一图元并输出0个或者更多的顶点,这些顶点则将被作为点,线段或者三角形组。几何着色器可以通过修改顶点,加入新的图元或者去除其他数据来修正一个网格模型。几何着色器被设计为修改输入数据或者进行一定数量的拷贝。例如,几何着色器的一个作用就是生成6个拷贝的数据以同时绘制cube map的6个面;我们将在第十章中进一步学习。其也可以为高质量的阴影计算模型创建层级阴影映射贴图(cascaded shadow map)。其他一些收益于几何着色器的算法,如基于一个点的数据创建不同尺寸的粒子,毛皮渲染以及找出物体的边缘用于阴影算法。在之后的章节我们还会学习几何着色器的各种用法。

DX11中,我们可以让几何着色器支持instancing,也就是说基于某个图元几何着色器可以运行多次。几何着色器最多能输出4个stream。其中一个stream需要被传输至渲染管线的下一个阶段被继续处理。而我们也可以将这些stream作为render target传输至stream output阶段。

几何着色器必须以图元输入时的顺序来输出图元。这也意味着如果多个着色器核心并行运作,那么几何着色器的计算结果必须被排序,这也影响了几何着色器的性能。这个因素也到导致了集合着色器不能在一个draw call中创建或者复制大量的几何体。

在我们发出draw call之后,管线中只有三个阶段可以为GPU创建“任务”:光栅化,tessellation阶段以及几何着色器。由于几何着色器是完全可编程的,它是这三个阶段中自由度最大的。但在实际运用中,几何着色器的使用率并不高,因为其并不能完全发挥GPU的性能。在一些移动设备中,几何着色器由软件执行,所以其使用率更低。

3.7.1 Stream Output

标准的GPU管线流程是将数据传输至顶点着色器,之后光栅化三角形,并在像素着色器中处理这些三角形。过去的渲染管线中,渲染管线中的中间数据并不能被读取。而Shader Model 4.0引入了stream output这一理念。在顶点由顶点着色器处理之后(当然,也可以被tessellation和几何着色器处理),这些数据除了被传输至光栅化阶段,其还能作为stream被输出,例如,以排序的数组形式。事实上,我们可以完全关闭光栅化,这样管线就是一个完全非图形的流处理器。以这种方式处理的数据可以经由管线回传。这一类型的操作可以适用于模拟水流或者其他粒子效果,我们将在第十三章中学习。其还可以为一个模型“蒙皮”,之后再次使用蒙皮后的顶点。

Stream output所范围的数据格式为浮点数,所以内存的消耗比较大。stream output则运用于图元,而不是顶点。如果网格模型被传输至管线,那么每个三角形都会生成其自身的三个输出顶点。原始模型中的任何顶点共享都会丢失。处于这个原因,stream output的用法是,直接将顶点作为图元传输至管线。在OpenGL中 ,stream output被称为transform feedback。图元在stream output中的输出顺序与其输入顺序一致,所以顶点的顺序并不会被打乱。

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据