渲染流水线
渲染流水线概念
渲染流水线的工作任务在于由一个三维场景出发、生成(或者说渲染)一张二维图像。换句话说,计算机需要从一系列的顶点数据、纹理等信息出发,把这些信息最终转换成一张人眼可以看到的图像。而这个工作通常是由CPU和GPU共同完成的。
渲染流水线的3个概念阶段
应用阶段–(输出渲染图元)–>几何阶段–(输出屏幕空间的顶点信息)–>光栅化阶段
渲染图元:渲染所需的几何信息,渲染图元可以是点、线、三角面等
应用阶段
- 应用阶段:开发者的主要任务首先准备好模型光源等;其次提高渲染效率做粗粒度剔除 (culling) 工作,剔除不可见物体;设置好每个模型的渲染状态(材质,纹理,shader等),最重要的输出渲染所需的几何信息,即渲染图元;这一阶段通常由CPU 负责实现;
几何阶段
- 几何阶段:处理几何相关事情,主要任务是决定绘制的图元怎么绘制在哪绘制 (输出屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色等相关信息) 把顶点坐标变换到屏幕空间中,这一阶段在GPU上进行;
光栅化阶段
- 光栅化阶段:将顶点数据 (纹理坐标,顶点颜色等) 进行插值,再进行逐像素处理。光栅化的任务主要是决定每个渲染图元中的哪些像素应该被绘制在屏幕上,在GPU上运行。
CPU和GPU之间的通信
渲染流水线的起点是CPU,即应用阶段。应用阶段大致可分为3个阶段:把数据加载到显存中,设置渲染状态,调用Draw Call
把数据加载到显存中
- 所有渲染所需的数据都需要从硬盘 (HDD) 中加载到系统内存 (RAM) ,而网格和纹理等数据被加载到显存 (VRAM) 中。显卡対显存的访问速度更快,但显卡对于RAM没有直接访问的权利。
- 当把数据加载到显存后,RAM中的数据可以移除,但如果CPU仍然需要访问的数据不能移除,因为从硬盘加载到RAM的过程十分耗时
设置渲染状态
- 渲染状态定义了场景中的网格是怎样被渲染的。如果没有更改渲染状态,那么所有的网格都将使用同一种渲染状态。
- 当渲染状态准备完毕后,CPU将会发出一条Draw Call命令通知GPU按照准备的数据进行渲染。
调用Draw Call
- Draw Call是一条命令,发起方是CPU,接收方是GPU。这个命令指向羽哥需要被渲染的图元 (primitives) 列表,而不会再包含任何材质信息 (在渲染状态中完成)。
- GPU接收Draw Call后,会根据渲染状态和所有输入的顶点数据进行计算 (计算过程为 GPU流水线 ) ,最终绘制屏幕上的像素。
GPU流水线
GPU渲染的过程就是GPU的流水线。
GPU渲染流水线图解
顶点数据是由应用阶段加载到显存,再通过Draw Call指定传给顶点着色器。
- 几何阶段
- 顶点着色器 (Vertex Shader) :可完全编程,通常用于实现顶点的空间变换、顶点着色等功能;
- 曲面细分着色器 (Tessellation Shader) :可选着色器,用于细分图元;
- 几何着色器 (Geometry Shader) :可选着色器,用于执行逐图元 (Per-Primitive) 的着色操作,或者用于产生更多的图元;
- 裁剪 (Clipping) :可配置,将不在摄像机是业内的顶点裁剪掉,并剔除某些三角图元的面片。
- 屏幕映射 (Screen Mapping) :不可配置和编程,将每个图元的坐标转换到屏幕坐标系中。
- 光栅化阶段
- 三角形设置 (Triangle Setup) 和 三角形遍历 (Triangle Traversal) 都是固定函数的阶段;
- 片元着色器 (Triangle Traversal) :可完全编程,用于实现逐片元的着色操作;
- 逐片元操作 (Per-Fragment Operations) :不可编程可配置,负责执行很多重要操作,修改颜色、深度缓冲、进行混合等。
顶点着色器 (Vertex Shader)
输入