乐趣区

关于程序员:可编程渲染管线Scriptable-Render-Pipeline-SRP

原文链接

可编程渲染管线解决数据的流程可分为以下 3 大阶段

1. 利用阶段

这个阶段大略会由 CPU 解决 4 件事件。首先会对模型数据进行可见性判断。模型数据由顶点地位、法线方向、顶点色彩、纹理坐标等形成。而后会将模型数据加载到显存以进步读取速度。再为每个图元设置常数寄存器和渲染状态。最初为一个渲染图元列表调用 DrawCall 指令。

图元能够是点、线、三角形。

2. 几何阶段

这个阶段由 GPU 进行解决,会对每一个须要渲染的图元进行逐顶点、逐多边形解决,最基本的工作是将顶点的模型坐标转换到屏幕空间。

2.1 顶点着色器

顶点着色器的根本工作是将顶点转换到齐次裁剪空间,还能够进行的其余工作有:

  • 逐顶点着色操作,如逐顶点光照
  • 纹理计算
  • 逐顶点蒙皮
  • 逐顶点程序式动画(procedural animation)

2.1.1 投影变换

透视投影

在摄像机应用透视投影的时候,为了呈现出近大远小的透视膨胀 (perspective foreshortening) 成果,须要对顶点进行透视投影变换。应用透视投影矩阵进行变换后,并没有进行裁剪,只是使得 w 值有了意义,为前面的裁剪做筹备。

Unity 透视投影矩阵(右乘)

会扭转空间手系,从右手系变成了左手系,因为 Unity 的察看空间是右手系,NDC 空间是左手系

察看空间中的顶点 (x,y,z) 透视投影到齐次裁剪空间后变为

透视投影齐次裁剪空间中坐标的 w 值为

正交投影

$ 正交投影远 (近) 裁剪立体高度 =2 \cdot Size$

Unity 正交投影矩阵(右乘)

会扭转空间手系,从右手系变成了左手系,因为 Unity 的察看空间是右手系,NDC 空间是左手系

察看空间种的顶点 (x,y,z) 正交投影到齐次裁剪空间后变为

正交投影齐次裁剪空间中坐标的 w 值为 1

2.2 曲面细分着色器

用于细分图元

2.3 几何着色器

  • 几何着色器的性能是批改、剔除、创立图元,能够实现以下成果:
  • 暗影体积拉伸(shadow volume extrusion)
  • 渲染立方体贴图 (cube map) 的 6 个面
  • 在网格的轮廓边拉伸毛发的鳍(fur in)
  • 从点数据生成例子四边形
  • 动静镶嵌
  • 把线段分形细分 (fractal subdivision) 以模仿闪电、布料
  • 将数据传到管线结尾从新进入管线

    • 用例:在顶点着色器内对头发样条的控制点进行物理模仿,在几何着色器内把样条镶嵌成线段,通过流输入将线段传到管线结尾从新进入管线进行渲染

      2.4 裁剪

      裁剪的作用是将每个三角形在平截头体以外的局部切掉,把在平截头体以外的三角形剔除。

满足以下条件的顶点才会被保留下来:

2.5 齐次除法

所谓的齐次除法就是让 x、y、z 都除以 w,这时就能够失去 NDC 空间中的坐标

上图左边都是 OpenGL 的 NDC,DirectX 的 NDC 也和上图左边相似,但 z 范畴在[0,1]

2.6 屏幕映射

视口空间:程序运行窗口形成的空间

矩阵中的 X、Y 是视口空间原点的屏幕坐标

3. 光栅化阶段

这个阶段由 GPU 来决定绘制哪些片元以及这些片元的色彩

片元 = 片段:三角形被栅格化后,其中的每一个小方块都是一个片元,能够看成是还不确定最终是否能够出现到屏幕上的像素

3.1 三角形设置

这个阶段的工作是找出三角形边界所笼罩的像素

3.2 三角形遍历

这个阶段会对每个三角形进行栅格化,即找出每个三角形笼罩的像素区域。区域中的片元中信息(屏幕坐标、深度值、法线坐标、纹理坐标)由 3 个顶点数据进行插值 (必要时会采纳透视校对插值) 失去

3.3 提前深度测试

如果用户没有在片元着色器中扭转深度或自我抛弃(discard),显卡会主动开启该性能

3.4 片元着色器

用于执行逐像素着色操作,如纹理采样、多重纹理采样、逐像素光照

3.5 逐片元操作

3.5.1 模板测试

if 开启了模板测试 then
    比拟参考值 (应用读取掩码) 和模板缓冲区中的模板值(应用读取掩码)
    if not 通过模板测试 then
        舍弃该片元
    end
    依据已设置的渲染状态更新模板缓冲区中的值(应用写入掩码)
end

3.5.2 深度测试

if 开启了深度测试 then
    比拟该片元的深度值和深度缓冲区中的深度值
    if 通过了深度测试 then
        if 开启了深度写入 then
            将深度值写入深度缓冲区
        end
    else
        舍弃该片元
    end
else
    if 开启了深度写入 then
        将深度值写入深度缓冲区
    end
end

3.5.3 混合

if 开启了混合 then
    用 alpha 混合函数 (alpha blending function) 将该片元的色彩值和色彩缓冲区中的色彩值进行混合
else
    间接应用该片元的色彩值
end
更新色彩缓冲区中的色彩值

小弟才浅,如果本篇文章有任何谬误和倡议,欢送大家留言

感激大家的点赞、珍藏

微信搜「三年游戏人」第一工夫浏览最新内容,获取一份收集多年的书籍包 以及 优质工作内推

退出移动版