渲染流水线的工作流程大致就是从一个三维场景出发生成或渲染出一张二维图像。这个工作过程是由CPU和GPU共同来完成的,大致分为以下3个阶段:
1、应用阶段
这部分通常由CPU负责实现,我们开发者对于这个阶段拥有绝对的控制权,大致可以分为以下三个阶段。
-
把数据加载到显存中(图元分配)
首先,将所有需要渲染的数据从硬盘加载到RAM系统内存。之后,网格和纹理等数据会被加载到显卡上的存储空间(显存)中,显卡对于显存的访问速度更快,而且大多数显卡对系统内存RAM没有直接的访问权利。
真实的渲染中需要加载到显存的数据非常复杂,例如:顶点位置信息,法线方向、顶点颜色、纹理坐标等。当我们把这些数据加载到显存之后,系统内存RAM中的数据就可以被移除了。但是对于CPU来说有一些数据是不希望被移除的,例如:需要访问网格数据来进行碰撞检测。
在这些准备工作之后,开发者还需要通过CPU来设置渲染状态来告诉GPU如何进行渲染工作。
-
设置渲染状态(编写shader材质)
渲染状态大致意思就是这些状态定义了场景中的网格是怎样被渲染的。例如:使用什么样的顶点着色器或片元着色器、光源属性、材质等。如果没有更改渲染状态的话所有的网格都将使用同一种渲染状态。在准备好这部分工作之后,CPU会发送一个渲染指令给GPU,这个指令就是Draw Call。
-
调用Draw Call
Draw Call实际上就是一个命令,是由CPU发起指令给到GPU。这个命令仅仅会指向一个需要被渲染的图元列表,而不会包含任何的材质信息。当给定Draw Call时,GPU会根据相应的渲染状态和输入的所有顶点数据来进行计算,最终输出成屏幕上的像素。
2、几何阶段
这一阶段通常在GPU上进行,主要是用来处理所有和几何相关的事情,例如:决定需要绘制的图元是什么,该怎么去绘制,在哪里绘制。这一阶段最重要的任务就是把三维顶点坐标变换到屏幕空间中,之后再交给光栅化阶段去进行处理。通过对渲染图元进行处理并输出屏幕空间的二维顶点坐标、每个顶点对应的深度值,着色等相关信息。
3、光栅化阶段
这一阶段通常在GPU上进行,这一阶段的主要工作是从几何阶段获取数据来产生屏幕上的像素,并渲染出最终的图像。光栅化阶段决定每个渲染图元中的哪些像素应该被绘制在屏幕上,需要对几何阶段中得到的逐顶点数据进行插值计算,然后再进行逐像素处理。