渲染管线详解
渲染管线
这是我在找工作过程中总结准备的。 第二篇讲得很细。可能后面由更深理解时再重写或者更改。
应用程序阶段
CPU负责,对数据进行处理,剔除。为GPU输入对应物体的渲染状态(纹理,材质,着色器)。将数据输入渲染管线。
CPU对GPU发指令Drawcall 批处理
输入图元、shader以及shader属性、贴图。通过DrawCall传入:设置渲染状态-》绘制图元数据-》结束DrawCall
顶点数据 完全可控
输入装配阶段,顶点坐标、顶点颜色、顶点法线、纹理坐标。可以在片元阶段阶段计算片段光照信息输出到颜色缓冲器。顶点数据在流水线中以图元形式处理。用顶点缓存对象(Vertex Buffer O)共享顶点。
几何处理阶段
GPU主导,开始进入流水线
顶点着色器、投影变换、裁剪、屏幕映射。
顶点着色器 完全可控
执行着色器的地方叫做SM,顶点着色器以及片元着色器都是在这一部分运算。warp就是由32个线程组成的线程束,是SM的基本单位。shader用到的warp越多越快。
顶点变换和顶点着色,局部坐标通过模型矩阵变换到世界坐标,世界坐标通过观察矩阵变换到观察坐标,观察坐标通过投影矩阵到裁剪坐标。(在图元组装部分进行)裁剪坐标通过投射除法到标准设备空间坐标,NDC通过视口变换到窗口坐标。
光照计算一般在世界空间进行,存在非均匀变换则需要通过矩阵逆的转置进行法线变换。
裁剪空间就是一个以原点为中心的立方体,不在裁剪空间的图元就会被裁剪。
正交投影
透视投影,使用齐次坐标,在透视除法阶段获得NDC坐标,由硬件自动完成。
Flat Shading 由一个顶点颜色作为整个三角形的颜色。
Gouraud Shading 逐顶点着色 在顶点着色器完成,在光栅化阶段插值得到各片段的光照信息。但高光结果不行,因为高光不是线性变化的。
Phong Shading 逐片段着色,根据输入的顶点法线信息在光栅化阶段进行法线插值,然后在片段着色器中计算光照信息。
曲面细分着色器
镶嵌化技术进行三角形细分,增加三角形的数量。可选。由外壳着色器、镶嵌器、域着色器。
贴图置换
不使用高模是因为:1.可以通过GPU实现动态LOD 根据物体和相机之间的距离调整细节 随着距离拉近可以连续镶嵌化处理增加细节。2.节约内存
几何着色器 完全可控
可选 完整的图元输入数据 输出可能输出多个图元也可能不输出。将一个点扩展成一个四边形。 公告栏效果。
图元组装
将输入的顶点组装成指定的图元。在光栅化前,通过裁剪和背面剔除为光栅化提供在视锥体中的图元。(下一步)还会进行透视除法以及窗口转换
裁剪 完全位于视锥体外的图元会裁剪 部分位于视锥体的图元则是裁剪 在边界处增加新的顶点。
但实际上不裁剪直接传入光栅化。只做保护带裁剪,将超出视口但不会产生整数型精度溢出的部分称为保护带。
裁剪使用的是齐次坐标则通过透视除法得到NDC,再通过视口转换得到屏幕坐标。
背面剔除 剔除那些背对摄像机的图元,根据环绕顺序,逆时针为正。或者通过行列式。
屏幕映射 不可控
透视除法 通过硬件自动完成 通过透视除法可以得到标准设备空间坐标,也可以成为标准视体CVV。正交投影或者是透视投影都会经过透视除法,只是正交投影w分量为1.齐次坐标记录下投影变换前正确的深度信息。
视口变换 不可控 与硬件无关,屏幕坐标是2D概念,窗口是2.5D存在深度信息。
就是将顶点从3D映射到2D投射在屏幕上,z轴留给光栅化阶段使用。
视口变换反向就是拾取变换。
光栅化 复杂而不可控
扫描转化,将屏幕空间的图元离散化为片元的过程。分为三角形组装和三角形遍历。
三角形组装 对输入的顶点数据进行插值。
三角形遍历 遍历三角形图元覆盖了那些片段的采样点。
线段扫描转换
DDA Bresenham
多边形填充
像素处理阶段
像素着色器和混合。
1.顶点着色器到片元着色器的插值 硬件控制 不可控
2.Early Z/Stencil Test 剔除一些被遮挡的三角形 不可控
3.将参数传递给片元着色器,通过GPU的L1 L2缓存进行。 不可控。
片段着色器 可控
实际上处理的不是一个片元而是2*2的片元。
决定屏幕上像素的最终颜色,进行光照以及阴影处理。
测试混合阶段
裁剪测试、Alphua测试、模板测试、深度测试
1.lateZ 计算图元的Z值与缓存中的Z值大小,是否更新。
2.stencil 记录图元位置的离屏缓存,可以改变颜色缓存和深度缓存。
3.blend
参考
https://zhuanlan.zhihu.com/p/430541328
https://positiveczp.github.io/细说图形学渲染管线.pdf
https://zhuanlan.zhihu.com/p/137780634