作者:王子饼干 ——镇江虹视游戏科技有限公司联合创始人、《多洛可小镇》制作人
原文链接:UnityShader入门精要笔记1:渲染流水线
原文发布时间:2020年2月22日
文章类型: 授权转载
渲染流水线,它的含义正如名字一样,可以分开解释,即渲染,和流水线。说白了,它是负责渲染的一个流水线。流水线的本质是一个工作流程,它可以简单的解释为,有一定的输入,经过一定的处理,得到一个输出。它(渲染流水线)的输入可能是一个摄像机,一堆模型,一些着色器,纹理等。它的输出就是渲染在屏幕上的一幅图片。
我们所要学习的着色器,它负责处理渲染流水线当中的一个过程。
渲染流水线有3个大体的阶段,每个阶段又包含多个子阶段。这三个阶段分别是应用阶段,几何阶段,光栅化阶段。
应用阶段又大概可以分为三个子阶段,分别是
顶点着色器的处理单位是顶点,也就是输入的每个顶点都会执行一次顶点着色器。它本身不能创建或者销毁顶点,也无法得知顶点之间的联系,正因为这样的相互独立性,GPU可以利用本身的特性并行化处理每个顶点,这使得顶点着色器处理的速度会非常快。
顶点着色器主要完成的任务是坐标变换和顶点变形。通过一些特定的算法,可以对顶点的位置进行偏移,这样会使得模型被扭曲,达到变形的效果。通常用于制作风吹动的效果或者水面效果。而坐标变换则是一个顶点着色器要处理的最基本的任务。
v.pos = UnityObjectToClipPos(v.vertex);
类似上面这行代码就可以把顶点坐标转换到齐次裁剪坐标空间下,接着由硬件做透视除法,最终得到归一化的设备坐标。
需要注意的是,OpenGL给出的坐标范围正如Unity所使用的坐标范围那样,它的分量的范围在-1和1之间,而在DirectX中,这个范围是0到1
屏幕映射的功能是把三维坐标系映射到二维坐标系,也就是屏幕坐标系(Screen Coordinates) 下。它和分辨率有很大的关系。
假设我们需要场景渲染到一个窗口上,窗口最小的坐标是(x1,y1),最大的坐标是(x2,y2),其中x1<x2,y1<y2。由于我们输入的坐标范围在-1到1,所以它会对图像进行一个缩放。而z坐标会和屏幕坐标合并在一起,传入光栅化阶段。
光栅化阶段中的三角形设置和三角形遍历会协同几何着色阶段所传递的一系列片元信息进入片元着色器,由片元着色器来决定最终应该渲染成什么样子,而片元着色器的定义则完全由用户决定。这也是我们所需要学习的内容。
在该部分当中,我们可以完成很多重要的渲染技术,例如纹理采样。为了在片元着色器中进行纹理采样,我们通常会在顶点着色器阶段输出每个顶点对应的纹理坐标,然后经过光栅化阶段对三角形网格的3个顶点对应的纹理坐标进行插值后,就可以得到其覆盖的片元纹理的坐标了。
这是渲染的最后一步,逐片元操作是OpenGL的说法,在DirectX中,该阶段被称为输出合并阶段,合并这个词更能概括该阶段的目的。这一阶段有一些主要任务
该阶段是无法编程的,但是可以高度配置,Unity为我们提供了一些关于深度测试,模板测试,以及混合的命令。可以让我们对以下的流程进行一定的控制。
如果一个片元通过了模板测试和深度测试(假设开启了这两个测试),那么它就可以与颜色缓冲区的颜色进行混合,混合有两种类型,第一种如果是不透明物体,那么会直接覆写颜色缓冲区的颜色,否则则以在混合操作中给定的混合因子对目标进行混合。
实际来说,由于一个片元最终没有通过测试的话,那么之前的努力就全部白费了,所以在真正的计算该片元的各种信息之前,我们应该先对其进行测试。Unity给出的渲染流水线中,深度测试确实也是在片元着色器之前的。将深度测试提早进行的技术通常也被称为Early-Z技术。