咱們先大概瞭解一下對渲染的優先級有影響的幾個因素緩存
一、Camera.Depth測試
不一樣相機的深度,在渲染順序的優先度裏面是最高的,Depth越大,渲染的圖像越靠前spa
二、Render.SortingOrder.net
也叫 SortingLayer 能夠理解爲一個渲染層Group。優先級高於RenderQueue。數值越大表示渲染在上層,也就是後繪製3d
三、material.RenderQueueblog
顧名思義,渲染隊列。數值越大越晚繪製。隊列
四、Z 也就是深度,Z值越大,離相機越遠,繪製順序越靠前。it
咱們以UI爲例,UI相機是正交相機,Z(深度)對UI來講就是雞肋。因此在NGUI中,都是以一、二、3這三個屬性來控制UI的顯示層級。渲染優先順序能夠理解爲深度優先搜索,即先渲染Camera.Depth最低的Render.SortingOrder最低的RenderQueue最小的Renderer。同時由於深度對繪製順序沒有什麼影響,因此UI的Shader通常都是關閉寫深度 (ZWrite Off),好比Unity自帶的Transparent Colored.shader。渲染
而後還有渲染的最後一道關ZWrite 深度緩存 和 ZTest深度測試 。搜索
引用一下別人的文字寫的定義。
原文:https://blog.csdn.net/lyh916/article/details/45317571
(1)什麼是深度?
深度其實就是該像素點在3d世界中距離攝像機的距離。離攝像機越遠,則深度值(Z值)越大。
(2)什麼是深度緩存?
深度緩存中存儲着準備要繪製在屏幕上的像素點的深度值。若是啓用了深度緩衝區,在繪製每一個像素以前,OpenGL會把該像素的深度值和深度緩存的深度值進行比較。若是新像素深度值<深度緩存深度值,則新像素值會取代原先的;反之,新像素值被遮擋,其顏色值和深度將被丟棄。(深度主要起的是比較的做用)
(3)什麼是深度測試?
在深度測試中,默認狀況是將要繪製的新像素的z值與深度緩衝區中對應位置的z值進行比較,若是比深度緩存中的值小,那麼用新像素的顏色值更新深度緩存中對應像素的顏色值。
(4)爲何須要深度?
在不使用深度測試的時候,若是咱們先繪製一個距離較近的物體,再繪製距離較遠的物體,則距離遠的物體由於後繪製,會把距離近的物體覆蓋掉,這樣的效果並非咱們所但願的。而有了深度緩衝之後,繪製物體的順序就不那麼重要了,都能按照遠近(Z值)正常顯示,這很關鍵。
那麼,在unity中,若是知道了渲染隊列,ZWrite,ZTest,如何肯定哪一個物體先顯示呢?
首先,unity先將渲染隊列中較前的進行渲染,而後再執行ZWrite,ZTest
ZWrite能夠取的值爲:On/Off,默認值爲On,表明是否要將像素的深度寫入深度緩存中(同時還要看ZTest是否經過)。
ZTest能夠取的值爲:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默認值爲LEqual,表明經過比較深度來更改顏色緩存的值。例如當取默認值的狀況下,若是將要繪製的新像素的z值小於等於深度緩存中的值,則將用新像素的顏色值更新深度緩存中對應像素的顏色值。須要注意的是,當ZTest取值爲Off時,表示的是關閉深度測試,等價於取值爲Always,而不是Never!Always指的是直接將當前像素顏色(不是深度)寫進顏色緩衝區中;而Never指的是不要將當前像素顏色寫進顏色緩衝區中,至關於消失。
那麼,重點來了:
1.當ZWrite爲On時,ZTest經過時,該像素的深度才能成功寫入深度緩存,同時由於ZTest經過了,該像素的顏色值也會寫入顏色緩存。
2.當ZWrite爲On時,ZTest不經過時,該像素的深度不能成功寫入深度緩存,同時由於ZTest不經過,該像素的顏色值不會寫入顏色緩存。
3.當ZWrite爲Off時,ZTest經過時,該像素的深度不能成功寫入深度緩存,同時由於ZTest經過了,該像素的顏色值會寫入顏色緩存。
4.當ZWrite爲Off時,ZTest不經過時,該像素的深度不能成功寫入深度緩存,同時由於ZTest不經過,該像素的顏色值不會寫入顏色緩存。
能夠看到,像素的深度可否成功寫入深度緩存,條件是ZWrite爲On,ZTest經過;
寫入深度緩存的做用就是爲ZTest的比較作準備。
由於ZWrite默認值爲On,ZTest默認值爲LEqual,因此這很好地解釋了爲何在unity中,距離相機近的東西會阻擋住距離相機遠的東西。若是咱們先繪製一個距離較近的物體,再繪製距離較遠的物體,則距離遠的物體由於後繪製,會把距離近的物體覆蓋掉,這時咱們能夠經過修改ZWrite和ZTest來改變物體的遮擋關係!
舉幾個實例:
在場景中拖兩個Cube,A是左邊的綠地材質,B是右邊的水材質。
示例1
Shader同時使用默認的Transparent Colored ,也就是ZWrite爲Off,ZTest爲Equal,RenderQueue不作修改,效果以下:
能夠看出是比較近的物體會繪製在上層。這種狀況就是生成的RenderQueue的順序影響繪製優先級,Untiy會按照深度調整生成的RenderQueue。繪製B的時候ZTest經過,重疊部分,B的像素點會寫入顏色緩存,替代A的像素點。
示例2
修改A的RenderQueue 爲3001,B的RenderQueue 爲默認(會從3000開始生成),效果以下圖:
這是由於指定了A的RenderQueue,A比B大,先繪製B後繪製A。繪製A的時候ZTest經過(由於B的深度數據沒有寫深度緩存因此能ZTest經過),重疊部分,A的像素點會寫入顏色緩存,替代B的像素點。
示例3
修改A的RenderQueue 爲3001,B的RenderQueue 爲默認3000,修改B的材質的Shader爲ZWrite On,即打開寫深度開關,效果如圖
圖1圖2
能夠看出,即便B的RenderQueue小於A,先繪製B後繪製A,可是因爲B寫入了深度緩存,圖2中的A ZTest不經過,因此B顯示在上層。
圖1是A ZTest經過的狀況。
示例4
修改A的RenderQueue 爲3001,B的RenderQueue 爲3002,B的材質的Shader爲ZWrite On,即打開寫深度開關,效果如圖:
能夠看出,因爲RenderQueueA比較小,先繪製的A,可是A不寫深度。繪製B的時候,B寫入了深度緩存,同時B ZTest經過,重疊部分,B的像素點會寫入顏色緩存,替代A的像素點。
例子差很少舉完了,實際項目中須要充分理解這些特性,實現特殊的層級效果!