Pipeline:每一步骤的输出都将作为下一步骤的输入,渲染过程在 GPU 中是并行运算的,蓝色背景部分可通过 shader 代码控制
1. Vertex Shader
顶点变换;坐标转换
2. Shape Assembly / 图元装配
将顶点转换为图元(在这里就是三角形面),并裁剪掉视野外的图元数据
3. Geometry Shader
通过增减顶点生成其他图元
4. Rasterization / 光栅化
光栅化是将一个图元转变为一个二维图像的过程,二维图像上每个点都包含了颜色、深度和纹理数据,这样的点就是片元 fragment
一个图元将转换为多个片元,并输入到 fragment shader 中
过程:4 个顶点光栅化后形成一个 10*10 像素的图形,则 fragment shader 将并行处理 100 次(Vertex shader 并行处理 4 次)
5. Fragment Shader
对片元进行纹理映射、灯光计算形成像素点
6. Test and Blend
在最后,fragment Shader 中输出的像素点还需要与 buffer 中存储的对应位置上的像素点(当前帧中渲染的其他物体)进行各种 test 与 blending 之后,形成最终显示在屏幕上的像素
Stencil Test (模板测试):
为 shader 中渲染的像素设置一个参考值 Ref ,然后与 stencil buffer 中对应像素点存储的值进行比较,通过的进行渲染否则丢弃
屏幕上每个像素点都有一个 stencil buffer 值,默认为 0,可被设置为 0 - 255
使用 Stencil test 时,通常做法是先用一个 shader 更新 buffer 值,在通过为其他 shader 设置 Ref 来与之前的 buffer 进行比较产生各种特效
Depth Test (深度测试):
默认情况下,将当前渲染像素的深度值与 Depth buffer 中对应像素点的深度值进行比较,如果比缓存中的值小,则用新的像素值替换缓存中对应像素点的值,有深度测试之后,物体的渲染顺序就不那么重要,都能按照深度值正常显示
ZWrite:开启时才写入深度值到 depth buffer 中,像素如果未写入深度值,则看起来没有远近效果
ZTest:通过 ZTest 的像素才能把深度值与颜色值写入到缓存中(在 ZTest 后,如果颜色值没写入缓存,则渲染像素在最终屏幕上将显示不出来颜色)
Blend (混合):
定义当前渲染像素与帧缓存(G buffer)中已渲染像素之间的混合方式
已渲染像素是指:当前帧中渲染的其他物体的像素,如另一片已渲染完成的草的像素
语法:Blend SrcFactor DstFactor (新渲染像素 * SrcFactor + 屏幕上已有像素 * DstFactor)
其他:
G buffer 中存储着:模板缓存(stencil buffer)、深度缓存(z / depth buffer)、颜色缓存(color / pixel buffer)等信息
参考文档:learnopengl 西川善司