About Modern Render Pipeline – Overview

【简介】
渲染管线(Graphics Pipeline/Render Pipeline)就是将数据从3D场景转换成2D图像,最终在屏幕上显示出来的总过程。如下图,就是如何将3D场景,灯光,纹理等数据转换成人眼可以看到的一张图片。主要包括两个功能:一是将物体3D坐标转变为屏幕空间2D坐标,二是为屏幕每个像素点进行着色。

这个过程通常是由CPU和GPU共同完成。可以分为三个阶段:应用阶段(Application Stage),几何阶段(Geometrty Stage),光栅化阶段(Rasterizer Stage)。
下图是GPU的渲染管线,细节流程如图所示。大的背景框范围,红色表示在CPU实现,蓝色表示在GPU实现。小矩形的颜色表示了不同阶段的可配置性或可编程性:绿色表示该流水线阶段是完全可编程控制的,黄色表示该流水线阶段可以配置但不是可编程的,蓝色表示该流水线阶段是由 GPU 固定实现的,开发者没有任何控制权。其中绿色部分,实线表示该 Shader 必须由开发者编程实现,虚线表示该 Shader 是可选的。

下面根据标签依次介绍:
【1 应用阶段 – CPU】
应用阶段是由应用主导的,开发者拥有绝对的控制权。这个阶段通常由CPU负责实现,有3个主要任务。
1.准备好场景数据。例如模型,光源,相机位置,视锥体等。
2.粗粒度剔除工作。为了提高性能,把不在视锥体范围内的物体剔除出去。
3.设置渲染状态。每个模型需要的材质,纹理,使用的shader等。

这一阶段最重要的输出是渲染所需的几何信息,即渲染图元(可以是点、线、三角面等)。这些渲染图源将会被传递给下一个阶段——几何阶段。

【2 drawcall – CPU和GPU之间的通信】
上面提到的是应用阶段的概念,这个阶段硬件真正做的事情主要为以下3件:
1.把数据加载到显存。所有渲染所需的数据都需要从硬盘加载到系统内存(CPU RAM)中,然后网格和纹理等数据又被加载到显存中(GPU 显卡内存)。
2.设置渲染状态。渲染状态定义了场景中的网格是怎样被渲染的,例如使用了哪个顶点着色器、片元着色器、光源属性、材质等。
3.调用DrawCall。DrawCall是一个命令,他的发起者是CPU,接受者是GPU。一个DrawCall指向本次需要被渲染的图元列表。

【3 几何阶段 – GPU】
几何阶段负责和每个渲染图元打交道,进行逐顶点、逐多边形的操作。这个阶段通常在GPU上进行,有一个重要任务就是把顶点坐标转换到屏幕空间中,再交给光栅器进行处理。

【4 顶点着色器】:主要任务是顶点的坐标变换(从模型空间转换到齐次裁剪空间;可以改变顶点位置做顶点动画),逐顶点光照计算等。

【5 曲面细分着色器】:曲面细分是对三角面进行细分,以此来增加物体表面的三角面数量。它由HullShader、Tessellator和Domain Shader构成,其中HullShader和Domain Shader是可编程的,Tessellator是硬件管理的。可以借助曲面细分技术实现LOD效果。

【6 几何着色器】:几何着色器的输入是完整的图元,输出可以是一个或多个其他的图元,或者不输出任何的图元。

【7 图元装配】:图元装配将输入的顶点组装成指定的图元。在这个阶段会进行裁剪和背面剔除等相关优化操作,以减少进入光栅化的图元的数量,加速渲染过程。
如下图所示,一个图元与摄像机视野的关系有 3 种:完全在视野内、部分在视野内、完全在视野外。
完全在视野内的图元会继续传递给下一个流水线阶段,完全在视野外得图元不会继续向下传递,部分在视野内的图元需要做裁剪处理,使用新的顶点来代替。

【8 屏幕映射】:在光栅化之前,还需要进行透视除法和屏幕映射操作。
透视除法:其实就是实现了一个投影变换,把“近大远小”的效果实现出来,把视锥体转为归一化的立方体(NDC)。
屏幕映射:即视口变换,把NDC中[-1,1]的坐标映射到二维的屏幕上[width,height]。

【9 光栅化阶段 – GPU】
这个时候我们将物体坐标变换到了窗口坐标。光栅化阶段是指矢量图形转化成像素点的过程。这个阶段也是在GPU上运行,主要任务是决定每个渲染图元中的哪些像素应该被绘制在屏幕上,并对上一个阶段中得到的逐顶点数据(例如顶点颜色,uv等)进行插值,然后再进行逐像素处理。

【10 三角形设置】:这一阶段,会计算光栅化一个三角网格所需的信息。上一阶段输出的是三角网格的顶点,如果我们想得到整个三角网格的覆盖情况,就必须计算每条边上的像素坐标而得到三角形边界的表示方式。这样一个计算三角网格表示方式数据的过程就是三角形设置。

【11 三角形遍历】:这一阶段会检查每个像素是否被一个三角网格所覆盖。如果被覆盖的话,就会生成一个片元。根据上一阶段的计算结果来判断一个三角网格覆盖了哪些像素,并使用三角网格 3 个顶点的顶点信息对整个覆盖区域的像素进行插值。这样一个找到哪些像素被三角网格覆盖的过程就是三角形遍历。

【12 片元着色器】:片元着色器的输入是上一个阶段对顶点信息插值得到的结果,输出是一个或者多个颜色值。这一阶段可以完成很多重要的渲染技术,其中最重要的技术之一就是纹理采样,需要在顶点着色器中输出每个顶点对应的纹理坐标。片元着色器可以完成很多重要的效果(比如进行光照计算以及阴影处理),但它仅可以影响单个片元。

【13 逐片元操作】:或者叫测试混合阶段。这个阶段主要任务是决定每个片元的可见性(包括模板测试,深度测试,Alpha测试等);通过所有的测试后,进入混合阶段,会把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行混合,然后写入颜色缓冲区。

【参考】
1.《Unity Shader 入门精要》
2.《Real-Time Rendering 4th》
3.渲染管线入门
4.渲染管线扫盲篇
5.图形渲染管线

Add a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注