渲染管线的作用:把3D元素转换成屏幕的2D图像
应用阶段
1.准备场景的基本数据:CPU从磁盘或是内存上读取模型或者贴图数据,将其加载进应用程序中。
-
场景物体数据
a. 物体变换数据:位置,旋转,缩放等
b. 物体网格数据:顶点位置,UV贴图等等
- 摄像机参数
a. 位置,方向,远近裁剪平面
b. 正交/透视(FOV)
c. 视口比例/尺寸等
- 光源和阴影信息
a. 光源:方向光,点光,聚光等以及各自的位置方向角度等信息
b. 设置阴影——是否需要阴影:判断改光源可见范围内是否有可投射阴影的物体;阴影参数:对于光源序号,阴影强度,级联参数,深度偏移,近平面偏移等
c.逐光源绘制阴影贴图——近平面偏移-逐级联
2.加速算法,粗粒度剔除:把被遮挡导致不可见的物体剔除也不参与后续计算。
- 可见光裁剪
- 可见场景物体裁剪(1.八叉树2.BSP树3.K-D树4.BVH)
3.设置渲染状态,准备渲染参数:对不同部分进行不同方式的渲染。
- 绘制设置:使用着色器,合批方式
- 绘制物体顺序(可以有多种方式):相对相机距离,材质RenderQueue,UICanvas等
- 渲染目标:FrameBuffer,RenderTexture...
- 渲染模式:前向渲染(ForwardBase ForwardAdd),延迟渲染
4.调用DrawCall,输出渲染图元到显存:把准备好的数据交到GPU处理
- 顶点数据:位置,颜色,法线,纹理uv坐标,其他顶点数据
- 其他数据:MVP变换矩阵,纹理贴图,其他数据
几何阶段
1.顶点着色
- 视图变换:将顶点坐标从模型空间转换到齐次裁剪空间
- 顶点着色:
-
顶点着色阶段的目的在于确定模型上顶点处材质的光照效果
2.可选顶点处理
- 曲面细分着色器(可选):通过现有顶点按一定规则和算法生成更多的顶点
- 几何着色器(可选):通过现有的图元做些几何方面操作,生成更多顶点和图元
3.投影
- 透视:左图W近处比较小远处比较大。当XYZ除W之后投影到2D屏幕近大远小
- 正交:右图, 把顶点在裁剪空间的XYZ除W=1,所以不会发生变化。不论远近都保持同样大小
4.裁剪
- 只有在单位立方体的图元才需要被继续处理。因此,完全在单位立方体外部的图元(红色三角形)被舍弃,完全在单位立方体内部的图元(绿色三角形)将被保留。和单位立方体相交的图元(黄色三角形)会被裁剪,新的顶点会被 生成,原来在外部的顶点会被舍弃
5.屏幕映射
- OpenGl的屏幕坐标原点在左下方,D3D在左上方
光栅化阶段
1.三角形设置:计算图元的边界信息
2.三角形遍历:计算边界信息包含的像素
光栅化过程 - 知乎 光栅化的过程
3.抗锯齿
- SSAA
A.渲染到一个分辨率放大n倍的buffer:屏幕分辨率1024x1024,渲染得到buffer可为2048x2048,放大四倍,对其采样后再输出屏幕
B.对方打n倍的buffer下采样
- MSAA
A.只有它发生在光栅化阶段
B.计算多个覆盖样本:覆盖测试看子采样点是否在三角形以内,遮挡测试看这个子采样度的深度和,即与深度缓存中数值进行比较,看能否通过,若能通过两测试,则说明采样点属于三角形,得到覆盖信息并保存,用于之后的着色混合
- FXAA/TXAA
片段着色器:使用这些点的数据进行着色,并为后面片元着色器准备
逐片元操作
1.片元着色
- 我们通过三个顶点的颜色得到P值的颜色,还能获取到其他的数据,比如UV信息,深度信息等,然后用片元数据和其他的全局数据,比如光照阴影时间等等去计算,得到最终的片元颜色
2.颜色混合
- 透明度混合:透明度小于给定阈值的片元就会被舍弃而不渲染,随着阈值的增大,一些颜色的透明度阈值小于给定的阈值,就会变透明
- 深度混合:片元深度和对应深度缓存的深度值作比较,通过就会保留
- 模板测试:同上,比较模板值
-
根据透明度,模板值,深度值混合
后处理