计划对游戏引擎图形学知识进行系统性学习,目的是实现特定的渲染效果以及拥有良好的性能。首先我想以计算机图形显示系统为出发点来理解渲染管线,这样比较容易和我们的现实生活实践联系起来,有利于理解知识点在其应用领域中所处的位置,从而形成画面感。
“理论联系实际”是对马克思主义普遍真理同革命和建设的具体实践相结合原则的概括表述。
图:计算机图形显示系统(For游戏应用)
什么是渲染
指把给定场景中的对象交由渲染程序生成一张二维图像数据的过程。
对象主要包括:
- 物体的模型,材质、纹理、坐标等
- 照相机的位置及朝向
- 光源信息等
大致流程
- 程序应用阶段(CPU)
- 几何阶段
- 顶点阶段
- 图元装配(几何体转换)
- 光栅化
- 片元输出
- 像素着色
- 后处理
- 输出到帧缓冲
一 程序应用阶段
- 准备好要渲染的场景数据,如:模型,相机,灯光等信息;
- 其中需要对非渲染对象和不可见对象排除;
- 最后设置好每个即将渲染的模型所对应的渲染状态。渲染状态包括但不限于材质,纹理,Shader等;
- CPU提交渲染数据到GPU前端模块(寄存器)中,只是一个图元对象记录列表(不包含模型,材质信息)。
PS:批处理
CPU在游戏程序中的主要职责包含两个部分:设置渲染状态和调用DC(不考虑复杂的脚本或者物理模拟的情况下)。 其中设置渲染状态属于比较重要的分工,如果每个物体的材质和贴图等都不一样,游戏的运行可能会比较缓慢,因为此时CPU的主要工作就是设置这些物体的渲染状态(当然调用DC也会更多,但渲染状态的改变更消耗性能)。
所以在常见的游戏中,1 对于大量的不需要改变位置的物体,都会采用静态批处理的方式;2 对于一些共享材质的物体可以采用动态批处理的方式;来解决设置渲染状态的性能瓶颈。
二 几何阶段
这是一个三维几何信息转换成二维几何信息的过程。
1 顶点阶段
坐标转换是图形硬件渲染管线种的第一个处理阶段。顶点变换在每个顶点上执行一系列的数学操作。这些操作包括把顶点位置变换到屏幕位置以便光栅器使用。
2 几何体转换
根据输入的vertices(顶点数据集),通过曲面细分着色程序生成更小更多的小的简单的图形,另外需要执行以下流程:背面裁剪–>光照–>裁剪–>投影–>视图变换,最终得到裁剪好的图元(点,线段或多边形)作为下一阶段的输入。
三 像素阶段
1 光栅化:光栅化阶段将裁剪好的图元转换为片元信息。
一个片元包含的信息有:
- 屏幕坐标
- 深度信息
- 顶点信息
- 法线信息
- 纹理坐标
- 颜色信息等等,
这些信息大部分在Vertex Processing中就已经存在。
2 片段着色器/像素着色器:输出像素。
四 后处理阶段
主要处理镜头特效:镜头模糊,镜头光晕/辉光,AO环境光遮蔽,扭曲等。
五 输出到帧缓冲
包括:颜色缓冲,深度缓冲,模板缓冲等多个缓冲区。
六 扩展:前向渲染与延迟渲染
以上是完整的渲染管线,但是也可以不同的情景进行定制以达到更优的性能。
前向渲染,适合半透明对象,因为半透明对象不能深度写入,只能按顺序从后往前一层一层渲染(这也是粒子特效消耗性能的原因)。
延迟渲染,效率更高,但需要更多的内存空间(一次存储所有延迟对象的顶点信息,片元信息等),且只能对深度测试最顶层的对象一并渲染,不需要反复走完整的渲染流程(只需要多次执行逐像素计算及之后的阶段)。