基本介绍

在《Real-Time Rendering, Third Edition》一书中,将一个渲染流程分为三个阶段:应用阶段几何阶段光栅化阶段。整个渲染三阶段相当于一个流水线工作,每个阶段还能继续细分,而每个阶段也相当于一个流水线工作。
渲染管线就是将数据分阶段的变为屏幕图像的过程。

渲染流水线中的三个概念阶段

其中,应用阶段是完全由我们的应用主导的,通常由CPU负责实现,开发者具有这个阶段的绝对控制权:在该阶段中,我们需要准备场景数据,例如摄像机的位置、视锥体、场景中包含了哪些模型、使用了哪些光源等等;或者设置好颗粒度剔除工作;最后还有各种模型的渲染状态。

这一阶段最重要的输出是渲染所需的几何信息,即渲染图元

几何阶段用于处理所有和我们要绘制的几何相关的事情,该阶段的一个重要任务就是把顶点坐标变换到屏幕空间中,再交给光栅器进行处理。对输入的渲染图元进行多步处理后,这一阶段将会输出屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色等相关信息,并传递给下一个阶段。

光栅化阶段将会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。

应用阶段

该阶段主要分为三个小阶段:(1)把数据加载到显存中。(2)设置渲染状态。(3)调用Draw Call。

传递的这些数据叫做帧缓存

把数据加载到显存中

渲染所需要的数据,从硬盘加载到RAM内存,最后加载到显存中。在渲染时,GPU可以快速访问这些数据

tips:把数据加载到显存中后,RAM中的数据就可以移除了(部分,有一部分如果还需要被使用可能就不移除)

设置渲染状态

这些状态定义了场景中的网格是怎样被渲染的。例如,使用哪个顶点着色器/片元着色器、光源属性、材质等。如果我们没有更改渲染状态, 那么所有的网格都将使用同一种渲染状态。

在同一状态下渲染3个网络。由于没有更改渲染状态,因此3个网络的外观看起来像是同一种材质的物体
调用Draw Call

Draw Call是一个命令,由CPU发起,指向GPU,这个命令仅仅会指向一个需要被渲染的图元列表,而不会再包含任何材质信息。

如果Draw Call过多,就会导致CPU过载,从而引起电脑卡顿。为解决该问题一般可以使用批处理方法:合并网络,共用材质,合并图集

GPU流水线

几何阶段光栅化阶段,开发者无法拥有绝对的控制权,实现的载体是GPU。虽然无法完全控制,但是GPU也向开发者提供了一些控制权。

几何阶段和光栅化阶段可以分成若干更小的流水线阶段,这些流水线阶段由GPU来实现,每个阶段GPU提供了不同的可配置性或可编程性。

绿色表示该流水线阶段是完全可编程控制的,黄色表示该流水线阶段可以配置但不是可编程的,蓝色表示该流水线阶段是由GPU固定实现的,开发者没有任何控制权。实线表示该Shader必须由开发者编程实现,虚线表示该Shader是可选的

图元:在渲染管线中,图元是指几何数据的基本单元,他是构成几何体的最小可绘制的单元。图元可以是点、线、三角形(顶点组成的),在几何阶段,顶点数据会被组合为图元,这些图元在光栅化阶段被转化为像素,最终呈现在屏幕上。

几何阶段

顶点着色器

顶点着色器是完全可编程的。
主要完成的工作有三:
1.坐标变换——顶点变换,法线变换,纹理坐标变换
2.顶点属性处理——对顶点的其他属性进行处理,比如颜色、透明度、切线向量等、可以用于实现顶点的动画、着色、光照等效果
3.顶点插值——计算顶点属性的插值值

曲面细分着色器、几何着色器

可选择性的学习,且需要硬件支持,本文暂时不学习(

裁剪

由千我们的场景可能会很大,而摄像机的视野范围很有可能不会覆盖所有的场景物体,那些不在摄像机视野范围的物体不需要被处理。而裁剪就是为了完成这个目的而被提出来的。
完全在视野内的图元就继续传递给下一个流水线阶段,完全在视野外的图元不会继续向下传递,因为它们不需要被渲染。而那些部分在视野内的图元需要进行一个处理,这就是裁剪。例如,一条线段的一个顶点在视野内,而另一个顶点不在视野内,那么在视野外部的顶点应该使用一个新的顶点来代替,这个新的顶点位于这条线段和视野边界的交点处。

屏幕映射

不太好讲,会涉及到一些线性代数的矩阵变换,从世界坐标系到摄像头的空间坐标系,暂时先不补充。

光栅化阶段

光栅化阶段主要做的事情是根据几何阶段输入的信息计算每个图元覆盖哪些像素,以及为这些像素计算他们的颜色等等工作。(相当于把抽象的信息转换为人眼看了能够理解的信息的预处理步骤,连接 “虚拟几何” 与 “屏幕图像” 的关键步骤)

三角形设置

这个阶段会计算光栅化一个三角网格所需的信息。具体来说,上一个阶段输出的都是三角网格的顶点,即我们得到的是三角网格每条边的两个端点。但如果要得到整个三角网格对像素的覆盖情况,我们就必须计算每条边上的像素坐标。
人话:之前只是所有的点都有了,但是还没连起来,这里就是确定点之间的关系,让他们都连起来,才能观察接下来的操作。

三角形遍历

三角形遍历阶段将会检查每个像素是否被一个三角网格所覆盖。如果 被覆盖的话,就会生成一个片元。而这样一个找到哪些像素被三角网格覆盖的过程就是三角形遍历,这个阶段也被称为扫描变换。(插值:通过已知数据点推算未知数据点的方法,实现从离散数据到连续数据的扩展)

根据几何阶段输出的顶点信息,而片元中的状态是对3个顶点的信息进行插值得到的。例如,对图中3个顶点的深度进行插值得到其重心位置对应的片元的深度值为-10.0

逐片元操作

输出合并阶段,主要完成对片元着色器的输出数据(最终颜色、法线、纹理坐标、深度等)的各种处理和计算。该操作主要完成的工作有:
1.决定每个片元的可见性,比如深度测试、模板测试
2.如果通过了所有的测试,需要把片元的颜色值和以及存储在颜色缓冲区的颜色进行合并(混合)等

补充内容

顶点着色器和片断着色器的执行次数是不一样的,如下图,顶点着色器执行三次,二片断着色器会执行25次,计算的复杂度是不一样的。
能在顶点里面做的事绝对不在片断里面做!