一、unity渲染管线完整的渲染流程图
二、具体流程
1.CPU应用阶段
①.剔除
在视椎体之外的模型直接剔除。
②. 排序
先渲染离摄像机近的不透明的物体,(从前到后渲染)后面有位置重合的就不用再渲染了。
如果是半透明物体,从后到前渲染保证渲染效果的正确性。
③.提交Drawcall,提交模型数据
2.GPU渲染管线:GPU渲染管线的内容 包括顶点处理---光栅化操作--片元处理--输出合并
①.顶点处理
模型空间通过模型矩阵转化转到世界空间,由统一的坐标系描述场景里所有的游戏对象。2.放好相机,从相机的角度观察这些物体,是经过视图矩阵,把模型顶点变化到相机空间的位置。3.模拟投影成像,近大远小的透视规则,用投影矩阵变化到裁剪空间,所以,最后通过顶点Shader变到最后一个压扁的形态。这三个矩阵合起来叫MVP矩阵,直接把模型空间转化到裁剪空间。经过顶点Shader后,就到了硬件操作阶段(光栅化阶段)。
②.硬件操作阶段(光栅化阶段)
- 经过裁剪操作,然后通过透视除法,从裁剪空间转化成NDC,把模型的顶点坐标缩放到(-1,1)之间,通过除以w就可以做到。轻松把顶点坐标映射到屏幕上。
- 背面剔除:背对着摄像机的面剔除掉,Z轴是摄像机的观察轴。去掉Z轴,在XY平面上,得到三角面在XY方向的截面,索引排列顺序是顺时针,就是一个背面,是逆时针分布,就是一个正面。
- 经过视口转换,转到屏幕坐标,就是把(-1,1)的区间,转化到1920*1080的区间,即转化到对应像素的坐标系,注意:转到屏幕坐标转换只针对XY坐标。Z坐标能判断面和点的前后关系。后面会有作用。到这步,已经很接近的完成投影成像的操作了,到现在还是一个个孤立的点。
- 然后进行图元装配,把点进行连线,生成一个个封闭的三角图形,这步叫做图元装配,每个三角形叫做一个图元。
- 光栅化:把每个图元通过差值计算,生成片元,即生成像素,但还不是真正的像素,所以叫做片元。光栅化过程就是把3D的顶点转化成2D的像素,把Z坐标忽略掉,三维图形变成二维图像,然后在2D的图像上做差值,生成片元。Z值也会差值计算储存到片元上,NDC上的Z值变成的每个片元的深度值,比如,一个位置有重叠的片元,可以通过Z值(深度)判断哪个应该显示在前面,处理前后遮挡关系。
③.片元处理
经过光栅化后,每个片元身上包括如下数据:深度值、法线、顶点色、切线、位置、所有自定义的数据。
这一阶段主要是光照着色和纹理着色。
④.输出合并
Alpha测试 如果Alpha值低于某个数值,就可以直接丢弃。
深度测试:深度值越小,说明离摄像机越近,渲染更优先显示出来
混合Blending:作用机制,渲染当前片元时,会拿到当前片元的颜色值Color,对比在相同位置上面的颜色缓冲区Color值,两个颜色值混合计算,得出一个新的颜色值。把新的颜色值放进对应的颜色缓冲区里。
3.帧缓冲
正是有了帧缓冲区的这种机制,模板测试、深度测试、混合操作才能顺利运行,因为这些操作是在帧缓冲区中的对应的颜色缓冲区、深度缓冲区、模板缓存区上做的一些操作。
用Shader代码可以控制ZWrite深度写入和ZTest深度测试,比如蓝色片元通过了深度测试,但是如果把ZWrite深度写入关掉后,即便通过深度测试,片元的深度值也不会写入到深度缓冲区。但是深度写入的机制并不会影响颜色缓冲区的一个正常写入,只要片元通过了深度测试,颜色值还会正常显示到颜色缓冲区,只是在深度缓冲区不会更新;ZTest深度测试可以设置通过测试的条件,本来正常是深度值比缓冲区深度值小,才能通过测试,但是也可以设置深度值比缓冲区深度值大才能通过测试。
输出合并完后,输出到帧缓冲区。我们的屏幕就可以从帧缓冲区里拿到对应的完整图像。