影响渲染顺序的因素
1、camera(depth越小,越先渲染)
2、sorting layer(值越小,越先渲染)(下面还有个sortingOrder 值越小,越先渲染)
3、渲染队列renderQueue(值越小,越先渲染)
4、深度值(距离相机越近该值越小,越远该值越大。)
1、camera
会先绘制depth低的摄像机,然后再绘制depth高的摄像机,depth高的会覆盖depth低的摄像机画面。
具体覆盖方式是根据摄像机的clearFlags来决定的
Skybox | Solid color | Depth only | Don’t clear |
---|---|---|---|
会直接覆盖掉 | 会直接覆盖掉 | 会叠加显示,但是会忽略掉3D位置信息,即当depth高的摄像机渲染的物体会遮挡depth低物体 | 会叠加,会保留位置信息,其实我的理解就是会保留深度信息 |
一个Cube坐标(0,0.5,1),layer=Default
一个Spehere坐标(0,0,2)layer=Water
单个相机照射,Cube会遮挡Sphere的一部分
当采用2个摄像机
MainCamera(depth=0 cullingMask=Default) ,
Camera_1(depth=1,cullingMask=Water)
当Camera_1采用Skybox,Solid color,界面只显示Camera_1的画面,显示Sphere |
当Camera_1采用Depth only,界面会显示2个相机叠加画面,但是Sphere会叠加在Cube的上面,Sphere会遮挡Cube的一部分。即depth高的Camera_1画面会在depth低的MainCamera下,原因我觉得是因为先渲染MainCamera,然后再渲染Camera_1,但由于不记录3D位置信息,也就是没有深度值的记录,所以Sphere总是会被写入颜色缓冲区,从而被绘制出来 |
当Camera_1采用Don’t clear,界面会显示2个相机叠加画面,保留了位置信息,Cube会在Spher的上面,Cube会遮挡Sphere的一部分,遮挡的那部分是因为该模式下,保留了深度信息,进行深度测试的时候,Sphere的深度大于Cube的深度,会不通过,从而不被写入颜色缓冲区。 |
Skybox,Solid color
depth only
Don’t clear
Don’t clear之所以能实现这样的显示,是因为我这里的材质设置的renderMode是Opaque,他的renderqueue是低于2500,属于不透明物体。该方式下的ZWrite是On的,ZTest 是LessEqual.
如果选用Transparent去就会出现不一样的结果,可以思考一下
因为ZWrite是Off的,先渲染了第一个摄像机的Cube,再渲染第二个摄像机的Speher时,虽然Speher深度值大于了Cube,但是因为Cube的深度写入是关闭的,默认的深度缓冲区还是一个非常大的值,所以Sphere的还是会写入颜色缓冲区。
2、sorting layer
主要应用于2D游戏中,越小的越先渲染。
当使用单个摄像机,且设定layer1<layer2
设置cube和Speher的renderQueue在(0,2500)或者(2500,5000)时,渲染顺序都是根据sorting layer来判定的Speher的Sorting layer小于Cube,所以总是先渲染Sphere
Cube.sortingLayerName = "Layer2";
Sphere.sortingLayerName = "Layer1";
Cube.renderQueue = 2000;
Sphere.renderQueue = 2001;
或者
Cube.sortingLayerName = "Layer2";
Sphere.sortingLayerName = "Layer1";
Cube.renderQueue = 3500;
Sphere.renderQueue = 3501;
但是当一个renderQueue位于0,2500)一个renderQueue位于(2500,5000),则Sorting layer生效的优先级就会下降。Unity总是先渲染小于2500的再渲染大于2500的。下图为
Cube.sortingLayerName = "Layer2";
Sphere.sortingLayerName = "Layer1";
Cube.renderQueue = 2000;
Sphere.renderQueue = 3500;
总是优先渲染Cube
3、渲染队列renderQueue
Properties | value | 渲染队列描述 | 中文书说明 |
---|---|---|---|
Background | 1000 | This render queue is rendered before any others. | 这个队列通常被最先渲染(比如 天空盒)。 |
Geometry | 2000 | Opaque geometry uses this queue. | 不透明几何体使用此队列 |
AlphaTest | 2450 | Alpha tested geometry uses this queue. | 需要开启透明度测试的物体。 |
GeometryLast | 2500 | Last render queue that is considered “opaque”. | 最后一个被认为是“不透明”的渲染队列。在所有Geometry和AlphaTest队列的物体渲染完后 |
Transparent | 3000 | This render queue is rendered after Geometry and AlphaTest, in back-to-front order. | 所有Geometry和AlphaTest队列的物体渲染完后,再按照从后往前的顺序进行渲染,任何使用了透明度混合的物体都应该使用该队列 |
Overlay | 4000 | This render queue is meant for overlay effects. | 该队列最后渲染,用于实现一些叠加效果 |
其中需要注意的一点是2500是一个分界线,unity总是先渲染不透明物体,即renderQueue小于2500的物体,再渲染大于2500的物体。
4、深度
越靠近摄像机深度越小,越小越先渲染。渲染的画面是否写入会根据深度测试结果来决定。
总结
1、当两个物体的renderQueue一个属于(0,2500)一个属于(2500,5000)
sortLayer就会优先级低于renderQueue
camera>renderQueue>sortLayer>深度
2、当两个物体的renderQueue都属于(0,2500)或者都属于(2500,5000)
camera>sortLayer>renderQueue>深度
camera永远是优先级最高的,如下图所示,
MainCamera(depth=0 cullingMask=Default) ,Camera_1(depth=1,cullingMask=Water),
虽然Sphere的renderQueue更小,但是因为摄像机MainCamera的深度更低,所以先渲染Cube
Cube.sortingLayerName = "Layer2";
Sphere.sortingLayerName = "Layer1";
Cube.renderQueue = 3000;
Sphere.renderQueue = 2002;