什么是渲染管线?
将素材通过一系列的加工最终显示在屏幕上,一系列的加工如同流水线一般。
渲染管线
渲染管线的工作是将一个三维场景出发,渲染成一张二维图像。这个过程由CPU,GPU共同完成。渲染流程分三个阶段:
应用阶段
在应用阶段开发者具有绝对的控制权。应用阶段分三个任务(CPU负责实现)
准备好场景数据。如场景所有GameObject信息,光照信息等。将数据加载到显存中。
硬盘-> RAM -> 显存
为了提高渲染性能,将相机不可见的物体剔除,这样就不用交给几何阶段处理了。
设置每个模型的渲染状态,如使用的材质,纹理,Shader等。输出渲染所需的几何信息,即:渲染图元,渲染图元可以是点,线,三角面等。这些渲染图元将会传递到下一个阶段。(调用DrawCall)
几何阶段(GPU)
几何阶段是用于处理所有要绘制的集合相关的事情。将上个阶段传递的渲染图元进行逐顶点,多边形进行处理。输出屏幕空间的二维顶点坐标,以及每个顶点的深度值,主色等相关信息,然后传递给光栅化阶段。这一阶段在GPU上进行。
光栅化阶段(GPU)
光栅化阶段会将上一阶段传递过来的数据生成对应屏幕上的像素,并渲染出最终图像。这一阶段也是在GPU上进行。
CPU与GPU的通信
渲染管线的起点是CPU,即应用阶段。应用阶段分为三个任务:
- 把数据加载到显存中。所有的渲染需要从硬盘(HDD)加载到内存(RAM)中,然后网格和纹理等数据又被加载到显存中,因为大多数显卡不能直接访问RAM,而且显卡读取显存速度也很快。当数据加载到显存后,RAM中一些CPU不再访问的数据即可移除掉了。但是之后还要使用的数据不能移除掉,毕竟从HDD加载到RAM还是很耗时的。之后通过CPU设置渲染状态进而指导GPU进行渲染。
- 设置渲染状态。渲染状态就是定义了场景中的网格该被如何渲染。如使用哪些顶点/片元着色器,光源属性,材质等。之后CPU调用DrawCall命令告诉GPU开始渲染。
- 调用DrawCall。DrawCall是一个渲染命令,由CPU发起,GPU接收。这个命令只会只想一个需要渲染的图元列表。当GPU收到DrawCall后,会根据渲染状态和顶点数据进行计算(GPU的流水线),最终显示到屏幕上。
GPU流水线
CPU向GPU传递渲染命令后,GPU经过一系列操作把图元显示在屏幕上。GPU阶段开发者没有绝对的控制权,即:无法控制这两个阶段的实现细节,但在不同的阶段会有不同的可配置性和可编程性。
顶点着色器(几何阶段)
- 通常用于顶点的空间变换,顶点着色等功能。(完全可编程)
- 数据来:CPU。每个输入进来的顶点都会调用一次顶点着色器。
- 顶点着色器不可创建、销毁任何顶点。
- 任务
- 坐标变换。最基本必须完成的变换:从模型空间转换到齐次裁剪空间。
- 逐顶点光照。
裁剪(几何阶段)
对于一个片元,在相机可视范围内就传递到下一个阶段,不在可视范围就舍弃掉,对于部分在可视范围内就需要对片元进行裁剪,只传递可视部分。(可配置)
屏幕映射(几何阶段)
把输入的三维坐标转换为二维屏幕坐标。(OpenGL左下角原点,DX左上角原点)
三角形设置(光栅化阶段)
片元着色器。
完全可编程。用于逐片元的着色操作。