一、渲染阶段
一般来说可以分为三个阶段:
应用阶段->几何阶段->光栅化阶段
# 二、应用阶段
在这个阶段,通常由cpu实现,主要的工作有:
- 准备场景数据
- 进行剔除工作
- 设置渲染状态
- 调用Draw Call
下面依次对各步骤进行介绍:
1.准备场景数据
准备场景数据这一步,将准备好摄像机、模型、光照等。
2.进行剔除工作
剔除工作有:视锥体剔除、层级剔除和遮挡剔除等。
其中视锥体剔除将把场景中摄像机视锥体外的物体剔除,不做处理,提高渲染性能。
3.设置渲染状态
简单来说,渲染状态决定了场景中的网格是怎样渲染的。而这一步就是设置场景中物体以怎样的方式来渲染。
4.调用Draw Call
Draw Call其实是一个命令,由cpu发出,gpu接收,这个命令指向一个需要被渲染的图元列表,gpu接收Draw Call以后,就会根据渲染状态和输入的顶点数据进行计算,最终将渲染结果输出到屏幕上。
至此,应用阶段结束。
三、几何阶段
几何阶段由gpu实现,其中有部分操作是可编程的,也有操作是不可编程的,也就是不可控的
本包括以下的一些步骤:
- 顶点shader
- 裁剪
- 屏幕映射
1.顶点shader
- 在这个阶段,顶点shader会对顶点坐标通过mvp矩阵进行坐标变换,将顶点坐标从模型空间转换到齐次裁剪空间。
- 接着再通过硬件进行透视除法得到归一化的坐标(Normalized Device Coordinates,NDC)。
2.裁剪
裁剪的操作是不可编程的,通过硬件操作。
首先要说明的是图元和摄像机视野的关系,有以下三种,对应的处理方式如下:
1)完全在视野内:这部分图元将直接传递到下一个渲染流水线阶段
2)完全在视野外:这部分不会传递,因为不需要渲染
3)部分在视野内:进行裁剪处理
下图显示了一种裁剪的过程:
可见,左边的图中有三个三角形图元,最左侧的图元由于完全在摄像机视野外,所以不会传递到下一个渲染流水线(右图)。中间的图元完全在摄像机视野内,所以直接传递到下一个渲染流水线。最右侧的图元有一部分在摄像机视野内,所以会进行裁剪处理,生成新的顶点,新的顶点为摄像机视野边界与图元边界的交点。
3.屏幕映射
这一步的作用是将场景渲染到窗口上,具体的操作就是将每个图元的三维坐标转换为屏幕坐标系下的坐标。过程如图所示:
四、光栅化阶段
光栅化阶段分为以下四个步骤:
- 三角形设置
- 三角形遍历
- 片元着色器
- 逐片元操作
1.三角形设置
这个步骤会接收来自上一阶段的顶点数据,计算三角形边界的像素信息,得到一个三角网格。
2.三角形遍历
- 这个步骤会检测哪些像素被三角形网格覆盖,如果被覆盖,就会生成一个片元。
- 三角形遍历会根据上一个步骤的网格信息判断网格覆盖了哪些像素,并且根据三角形网格的三个顶点进行插值运算遍历三角形网格内的像素。
过程如下图:
3.片元着色器
- 在这一步,片元着色器会对各个三角形遍历得到的片元根据插值运算得到的结果进行着色。
- 这一步还会使用一些重要的渲染技术,如纹理采样、MipMap技术、phong光照模型等,这里暂时不作介绍。
4.逐片元操作
在完成片元着色器步骤后,对于每个片元,会继续进行模板测试、深度测试和混合操作,最终成为显示在屏幕上的像素。下面简单介绍模板测试、深度测试和混合操作。
i.模板测试
模板测试的流程图如下:
ii.深度测试
深度测试的流程图如下:
iii.混合操作
混合操作的流程如下:
图源:《Unity Shader 入门精要》 冯乐乐