【笔记】【百人计划】图形1.1 渲染流水线

图形1.1 渲染流水线

一、概念流程

  • 应用程序阶段

    • 粗粒度剔除
    • 渲染设置
    • 准备基本数据
    • 输出到几何阶段(渲染图元
  • 几何阶段

    • 顶点着色器
    • 曲面细分
    • 几何着色器
    • 顶点裁剪(屏幕空间裁剪)
    • 屏幕映射(屏幕空间顶点信息
  • 光栅化阶段

    • 三角形(图元:点/线)设置,三角形(图元)遍历,片元着色器
  • 逐片元操作(合并)

    • 裁剪测试
    • 透明度测试
    • 模板测试
    • 混合
  • 后处理(图像空间的处理)

二、细节

1.应用阶段(CPU)

  • 准备基本场景数据(硬盘->内存)
    • 场景物体数据
      • 物体Transform:位置、旋转、缩放等
      • 物体网格数据:顶点位置,UV贴图
      • 这里的分类是不是有点像Maya的两种Dag类型Transform和Shape
    • 摄像机数据
      • 位置、方向、远近裁剪平面
      • 正交/透视(fov)
      • 视口比例/尺寸等
    • 光源及阴影
      • 光源类型:方向光、点光、聚光
      • 颜色、位置、方向、范围、角度等
      • 阴影设置
        • 是否需要阴影,判断该光源可见范围内是否有可投射阴影的物体
        • 阴影参数:对应光源序号、阴影强度、级联参数、深度偏移、近平面偏移
      • 逐光源绘制阴影贴图
        • 近平面偏移
        • 逐级联
          • 计算当前光源+级联对应的观察矩阵、投影矩阵、对应到阴影贴图里的视口区域
        • 绘制到阴影贴图
    • 其他全局数据
  • 加速算法/粗粒度剔除
    • 碰撞检测
    • 加速算法
    • 剔除
      • 可见光裁剪
      • 视锥剔除
      • 如CPU阶段的可见性(遮挡)剔除
        • Octree
        • BSP tree
        • K-D tree
        • BVH tree
    • 其他
  • 设置渲染状态,准备渲染参数(以unity为例)
    • 渲染设置
      • 使用着色器
      • 合批方式
    • 渲染顺序
      • 相对摄像机的距离
      • 材质Render Queue
      • UI Canvas
      • 其他
    • 渲染目标
      • Render Texture
      • Frame Buffer
      • 多个目标
    • 渲染模式
      • Forward
      • Deferred
  • 调用Draw Call,输出渲染图元到显存
    • 顶点数据
      • 位置
      • 颜色
      • 法线
      • UV texcoord
      • 其他
    • 其他数据
      • MVP
      • 纹理贴图
      • 其他

2.几何阶段

2.1顶点着色器

视图变换、顶点着色等
输出到Clip Space

2.2曲面细分着色器(可选)

网格、图元细分

2.3几何着色器(可选)

逐图元着色或者产生更多图元

2.4裁剪(不可编程)

正面或背面剔除(可配置)

裁剪的顺序

关于裁剪和透视除法的顺序,看到很多争议,包括参考图也有画在2D空间和3D空间的

在虎书4th的描述里,裁剪可能完成的地方有2种

  1. 使用6个平面围成的观察金字塔(view pyramid)的世界坐标系中
  2. 齐次坐标除法之前的4D变换空间

无论哪种都可以实现

1
2
3
4
5
6
7
for each of six planes do
if (triangle entirely outside of plane) then
break (triangle is not visible)
else if triangle spans plane then
clip triangle
if (quadrilateral is left) then
break into two triangles

而如果先做透视除法再做裁剪,透视变换保持了深度顺序,但是在0处不连续

image-20220720181336331

这样会把裁剪变得复杂,可能出现错误结果。

这部分的数学推导在后面整理到模型空间变换再研究好了。

总得来说,现代图形渲染管线,就是在齐次裁剪坐标下进行裁剪,然后由硬件完成透视除法。

至于书中提到的第一种裁剪位置在什么地方会用到就不知道了。实际上很多管线中的顺序也取决于硬件设计。

2.5透视除法

齐次裁剪坐标Clip Space下,硬件完成透视除法xyz/w,得到归一化的设备坐标NDC

Opengl和Unity的NDC的z分量范围在[-1,1]

DirectX中NDC的z分量范围是[0,1]

2.6屏幕映射(不可编程)

从连续到离散

坐标系差异(Opengl/D3D)

Opengl左下角为最小窗口坐标

Dx定义左上角为最小窗口坐标

3.光栅化阶段

3.1三角形设置Triangle Setup/图元装配Primitive Assembly

根据输入的网格顶点来计算三角形边界

3.2三角形遍历

(直线绘制算法与扫描线填充算法)扫描变换,检查像素是否被三角形覆盖,覆盖则生成一个片元

每个片元计算根据三角形顶点插值后的数据

因此片元和像素区别的意义不仅在于SSAA,还有合并操作当中,对同一像素对应片元进行合并才输出像素。

MSAA

对每个像素设置多个采样点,对每个子采样点进行覆盖测试和遮挡测试,每个子采样点都需要维护深度

3.3片元着色器

对于插值得到的片元执行片元着色器程序,输出一个或多个颜色值

4.逐片元操作(输出合并阶段)

决定每个片元的可见性

  • Alpha Test
    • 透明度小于阈值的片元就被舍弃
  • Stencil Test
  • Depth Buffer Test

如果通过测试,则把该片元颜色值和颜色缓冲区中的颜色进行合并/混合

  • Color Buffer Blending
    • Alpha Blend

输出到目标缓冲区(RT/FB)

5.后处理

  • HDR

  • Bloom

  • FXAA

  • Depth of View景深

  • 边缘检测

  • 径向模糊

  • 。。。

参考资料

[1] https://www.bilibili.com/video/BV1L54y1s7xw 【技术美术百人计划】图形 1.1 渲染流水线

[2] https://jishuin.proginn.com/p/763bfbd6e54f

[3] Unity Shader入门精要

[4] Fundamentals of Computer Graphics,4th