天天看点

shader入门精要读书笔记03 GPU流水线

10.19

一、光栅化阶段、

从上一阶段接收顶点位置信息,以及其他的额外信息(深度值(Z坐标)、法线方向、视角方向)

光栅化两个重要的目标:计算每个图元需要覆盖的像素,并为这些像素计算它们的颜色。

1.三角形设置

此阶段就是指使用上一阶段得到的三角网格的顶点计算出网格边界的像素坐标信息,也就是设置每个三角形网格的所有像素坐标。

2.三角形遍历

此阶段根据上阶段的计算结果来检查每个像素是否被三角网格所覆盖并使用三角网格3个顶点的顶点信息来对整个覆盖区域进行插值(用来估算深度信息),这个过程也叫 扫描变换。

最终得到的是一个片元序列,

一个片元并不是真正的像素,而是很多状态的集合(屏幕坐标、深度信息、还有一些法线、纹理坐标等的顶点信息),这些状态用于计算每个像素的最终颜色。

3.片元着色器

片元着色器是另外一个非常重要的可编程阶段。

片元着色器也叫像素着色器(在DX中),片元更合适只不过。

在此之前的光栅化阶段实际上并不会影响每个像素的颜色值,之前产生的都是一系列数据用来描述三角网格是怎样覆盖的每个像素,片元就是用来存储这些数据的。片元着色器之后的 “逐片元操作”才会对像素产生影响。

片元着色器的输入 大概就是就是顶点着色器的输出信息的插值运算。

片元着色器的输出是一个或者多个颜色值。

此阶段会完成很多重要的渲染技术,其中最重要的就是纹理采样。

纹理采样需要得到片元的纹理坐标,所以在顶点着色器阶段要输出每个顶点对应的纹理坐标,经过前面的光栅化阶段进行插值,计算出片元的纹理坐标,再在此阶段使用。

片元着色器只能对单个片元进行影响,不能把他自己的任何信息发送给他的邻居片元。(访问导数信息可以例外(gradient或derivative))。

4.逐片元操作

逐片元操作是OpenGL中的说法,DX中这一阶段被称为 输出合并阶段。

此阶段是高度可配置性的,我们可以设置此阶段的每一个详细操作。

此阶段是渲染流水线也是光栅化阶段的最后一阶段。

此阶段任务:

(1)决定每个片元的可见性,涉及很多测试工作,例如深度测试、模板测试等。

(2)如果一个片元通过所有测试,那就把颜色值和已经存储在颜色缓冲中的颜色进行合并。如果有任何一个环节没有通过测试,那么这个片元会被舍弃,之前做的所有工作也都白费了。

逐片元操作大致过程:

片元——>模板测试——>深度测试——>混合——>颜色缓冲区

5.模板测试

与之相关的是模板缓冲。(网上查:用缓冲区保存的值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新响应的像素点的颜色值。这个比较的过程称为模板测试。)模板缓冲是和颜色缓冲、深度缓冲、像素缓冲类似的另外一种缓冲。

开启模板缓冲后,GPU会首先读取(使用读取掩码)模板缓冲区中该片元位置的模板值,再将该值与读取(也使用读取掩码)到的参考值进行比较。

比较时比较函数我们可以自己指定,例如不同大小关系是否进行舍弃操作。

不管一个片元是否通过模板测试,我们都可以根据模板测试和下面的深度测试来修改模板缓冲区,修改操作我们也可以自己进行控制。

修改操作可以详细设置比如不通过时不变,通过时+1等等。

模板测试常用于限制渲染区域。

高级用法:渲染阴影、轮廓渲染。

6.深度测试

同样可以配置,设置比较关系(比较的是片元深度值和存在于深度缓存区中的深度值),一般设置为如果片元深度值大于等于当前当前深度缓冲区中的值,那么就会舍弃它。因为我们会想要距离摄像机更近的值。

与模板测试不同的是:如果一个片元没有通过此测试,那它就没有权利去更改深度缓冲区中的值。而如果通过的话,开发者甚至可以指定是否要用这个片元的深度值覆盖掉原有的深度值(通过更改 深度写入 的开启与关闭)。

透明效果与深度测试以及深度写入的关系非常密切。

6.合并

与之相关的是混合操作,他决定 我们这次渲染的颜色是完全覆盖掉之前上一次渲染的颜色,还是进行混合。

混合操作进行颜色混合时,GPU会取出源颜色(片元着色器得到的颜色值)和目标颜色(已经存在于颜色缓冲区中的颜色值),后使用一个混合函数(通常与透明通道相关,进行加减乘等)进行计算。

7.综述

上面说的测试顺序并不唯一,

可以进行测试后 再 片元着色器进行颜色计算。

也可以先进行片元着色器颜色计算,再进行测试。

Unity进行深度测试提前(Early-Z技术),这样可以进行提前判断,提高性能。

但若进行某些测试提前的话,可能会有冲突产生。

比如我们要在片元着色器中进行透明度测试,但是这个片元没有通过透明度测试,那么我们会调用API(例如clip函数)进行手动舍弃。这样就会导致无法提前进行各种测试。

所以现代GPU中,我们会判断片元着色器是否会与提前测试产生冲突,如果有冲突我们就要禁用提前测试,这样会造成性能上的下降(会有更多的偏远需要处理)。这也就是为什么透明度测试会影响性能上下降的原因。

最后,图元进行层层计算和测试后,就会显示到我们的屏幕上,

屏幕上显示的就是颜色缓冲区的颜色值。

此处GPU会采用双重缓冲的策略,去避免我们看到正在进行栅格化的图元。

所有正在进行光栅化的图元都是在幕后(后置缓冲中进行的),一旦后置缓冲中场景已经被渲染好,GPU就会交换后置缓冲与前置缓冲(之前显示在屏幕上的图像)中的内容。

这样也决定了我们看到的图象是连续的。

完事。。。