文章目录
阅读前的注意事项
该系列文章为个人对书中知识学习总结,详细知识点请参考《Unity Shader入门精要》一书。
渲染流水线
渲染流水线在概念上大致可以分为三个阶段:应用阶段、几何阶段、光栅化阶段。为了更简单直观地来理解渲染流程,我制作了一个思维导图,图中所列为较重要的知识点。大白话总结请直接跳转文末总结(图里的基本就是我想讲的所有内容,下面对其简单的补充)
一、应用阶段
CPU是渲染流水线的起点,简单说一下其主要任务。
1.把数据加载到缓存中
哪些数据?所有渲染需要的数据都需要。主要有顶点的位置信息、顶点颜色、法线方向、纹理坐标等。
2.设置渲染状态
渲染状态定义了一个网格是怎样被渲染的:使用哪些顶点/片元着色器、材质、光源属性等。如果没有更改渲染状态,那么所有的网格都使用同一种渲染状态。打个比方:一个正方形网格,一个圆形网格,不更改状态的话会看起来材质都一样。
3.调用Draw Call
Draw Call是一个命令,发起方是CPU,接收方是GPU,指向一个需要被渲染的图元列表(渲染图元可以理解为点、线、面等)。给定Draw Call后,GPU就会开始根据渲染状态和数据计算并输出像素。
二、GPU流水线之几何阶段
几何阶段重点是顶点着色器。顶点着色器会将模型顶点的位置变换到齐次裁剪坐标空间下,接着通常再由硬件做透视除法后,最终得到归一化的设备坐标(NDC)。讲点人话:顶点位置会改变,可以模拟水面、布料这些效果。
三、GPU流水线之光栅化阶段
光栅化最重要的在于片元着色器和逐片元操作。片元着色器在图里有解释过,解释一下逐片元操作中的两个测试。《Unity Shader入门精要》中的流程图很直观
1.模板测试
其中参考值和模板值的比较是通过比较函数实现的,该函数由开发者指定,比如说小于时就舍弃这个片元,最后的修改操作也由开发者指定,例如舍弃时模板缓冲区保持不变,通过时模板缓冲区中对应位置加一。模板测试常用于限制渲染的区域、渲染阴影、轮廓渲染等。
2.深度测试
深度测试中一般把比较函数设置为大于等于缓冲区值就舍弃,因为我们通常只想显示离摄像机最近的物体。但是要注意的是,它跟模板测试不同,如果没有通过测试,就不能修改缓冲区,即使通过了,也可以指定它是否要覆盖掉缓冲区原本的值。
3.混合
为什么要合并?渲染过程是一个物体接着一个物体画到屏幕上,每个像素的颜色信息都被存储在颜色缓冲里。因此,当执行本次渲染时,颜色缓冲中往往已经有了上次渲染后的颜色结果。合并解决的问题是直接用本次渲染的颜色结果覆盖之前的还是做其他处理。对于半透明物体通常使用混合来让它看起来像是透明的。
注意
以上测试的顺序不唯一,如果测试在最后,那么结果可能会是:经过GPU好不容易计算出片元的颜色最后没有通过测试然后被舍弃。通常会考虑把测试放在片元着色器阶段之前,例如下图:
需要考虑的是,片元着色器中的操作是否会和提前测试冲突,如果冲突,就禁用提前测试。
四、屏幕显示
GPU通冲采用双重缓冲。对场景的渲染在后置缓冲中,前置缓冲区的内容是屏幕上显示的图像,一旦场景被渲染到了后置缓冲,就和前置交换,保证我们看到的图像是连续的。
五、总结
简单的讲,就是CPU准备好了顶点的相关信息,设置好渲染状态,告诉GPU要开始渲染了,GPU就会把这些顶点数据进行计算,输出的片元颜色会根据测试的结果来决定。
以上为我对《Unity Shader入门精要》基础篇中关于渲染流水线的总结。