百人计划-渲染流水线

参考资料:
百人计划-渲染流水线
《Unity Shader入门精要》 第2章 渲染流水线

1 整体流程

  1. 应用阶段:粗粒度剔除,进行渲染设置,准备基本数据,输出到几何阶段
  2. 几何阶段:顶点着色器,曲面细分,几何着色器,顶点裁剪,屏幕映射
  3. 光栅化阶段:三角形(点/线)设置,三角形(点/线)遍历,片段着色器
  4. 逐片元操作:裁剪测试,透明度测试,深度测试,模板测试,混合
  5. 后处理

不同的教材和资料对渲染流水线的划分有所不同,有些将片元着色器和逐片元操作都归入光栅化阶段,有些将这两步独立为逐片元操作阶段,不用过于纠结。

2 应用阶段

1. 把数据加载到显存中
2. 设置渲染状态
3. 调用Draw Call

2.1 基本场景数据(把数据加载到显存中)

  1. 场景物体数据:Transform(位置,旋转,缩放)+ 网格数据(顶点位置,UV,法线,切线)
  2. 摄像机数据:参数(位置,朝向,远近裁剪面,透视方式,比例)
  3. 光源数据:类型(方向光,点光,面光)+ 参数(位置,方向,角度)
  4. 阴影数据:是否需要阴影,阴影参数(对应光源,强度,级联参数,深度偏移,近平面偏移)

2.2 优化(算法加速,剔除)

  1. 碰撞检测
  2. 加速算法
  3. 遮挡剔除(粗略):裁剪光源,物体(八叉树,K-D树,BVH)

2.3 设置渲染状态,准备渲染参数

渲染状态定义了场景中的网格是怎样被渲染的,例如使用哪个顶点着色器/片元着色器,材质,光源等等。

  1. 绘制设置:着色器,合批方式(减少Draw Call的方式使用批处理,合批方式决定哪些网格被合并)
  2. 绘制顺序:透明物体的渲染顺序
  3. 渲染目标:RenderTexture,FrameBuffer
  4. 渲染模式:前向渲染,延迟渲染

2.4 调用DrawCall

CPU 调用一个渲染命令来告诉GPU: “嘿!老兄, 我都帮你把数据准备好啦, 你可以按照我的设置来开始渲染啦!” 而这个渲染命令就是 Draw Call。

Draw Call中造成的性能问题主要来自CPU

调用完Draw Call之后,我们完成了CPU和GPU之间的通信,接下来进入了GPU流水线阶段,包括几何阶段和光栅化阶段。

GPU流水线不是完全可控的,但是GPU向我们开放了很多控制权,绿色表示完全可编程完全可控,黄色表示不可编程但可以配置,蓝色表示完全不可编程。

3 几何阶段

3.1 顶点着色器(vertex shader)


顶点着色器负责坐标变换和逐顶点光照,除此之外,顶点着色器也可以输出后续阶段所需的数据。

  1. 坐标变换:顶点着色器必须完成的一个工作是 把顶点坐标从模型空间转换到齐次裁剪空间(即完成MVP变换) Games101-变换
    还可以完成一些顶点动画来模拟水面,布料等。

3.2 裁剪


裁剪阶段是不可编程的,是硬件上的固定操作,但我们可以自定义个裁剪操作来进行配置

3.3 屏幕映射

屏幕映射就是一个缩放过程,其对z坐标不做任何变换。要注意OpenGL和DirectX的屏幕坐标系有所不同。

4 光栅化阶段

光栅化阶段有两个最重要的目标 计算每个图元覆盖了哪些像素,以及为这些像素计算它们的颜色。

4.1 三角形设置/图元组装(Primitive Assembly)

4.2 三角形遍历

三角形遍历(Triangle Traversal)检查每个像素是否被一个三角网格所覆盖,若覆盖则会生成一个片元(fragment),在这个阶段,GPU会对所有信息进行插值,也就是说对每一个片元来说其中包含了顶点位置,深度,法线等所有信息,这也就是为什么我们可以在片元着色器中仍然使用顶点计算光照并得到更好的效果。

需要注意:片元并不完全等于像素,片元中包含了很多状态(屏幕坐标,深度信息,法线,纹理坐标等等)

5 逐片元操作

5.1 片元着色器

片元着色器 (Fragment Shader) 是另一个非常重要的可编程着色器阶段。在 DirectX 中,片元着色器被称为像素着色器 (Pixel Shader), 但片元着色器是个更合适的名字,因为此时的片元并不是一个真正意义上的像素。

5.2 逐片元操作


逐片元操作 (Per Fragment Operations) OpenGL 中的说法 Direct.X 这一阶段被称为输出合井阶段 (Output-Merger),该阶段对每个片元进行操作,将它们的颜色以某种形式合并,得到最终在屏幕上像素显示的颜色。主要的工作有两个:

  1. 对片元进行测试(Test)
  2. 合并(Merge)

5.3 双重缓冲(Double Buffering)

为了避免我们看到那些正在进行光栅化的图元,GPU对场景的渲染是在幕后发生的,即在 后置缓冲 (Back Buffer) 中。 一旦场景已经被渲染到了后置缓冲中,GPU 就会交换后置缓冲区和 前置缓冲 (Front Buffer) 中的内容, 而前置缓冲区是之前显示在屏幕上的图像。

6 各阶段可控性

GPU流水线不是完全可控的,但是GPU向我们开放了很多控制权,绿色表示完全可编程完全可控,黄色表示不可编程但可以配置,蓝色表示完全不可编程。


百人计划-渲染流水线
https://kenny-hoho.github.io/2023/07/07/百人计划-渲染流水线/
作者
Kenny-hoho
发布于
2023年7月7日
许可协议