Unity渲染


我們先大概了解一下對渲染的優先級有影響的幾個因素

1、Camera.Depth

不同相機的深度,在渲染順序的優先度里面是最高的,Depth越大,渲染的圖像越靠前

2、Render.SortingOrder

也叫 SortingLayer 可以理解為一個渲染層Group。優先級高於RenderQueue。數值越大表示渲染在上層,也就是后繪制

3、material.RenderQueue

顧名思義,渲染隊列。數值越大越晚繪制。

4、Z 也就是深度,Z值越大,離相機越遠,繪制順序越靠前。

我們以UI為例,UI相機是正交相機,Z(深度)對UI來說就是雞肋。所以在NGUI中,都是以1、2、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的像素點。

例子差不多舉完了,實際項目中需要充分理解這些特性,實現特殊的層級效果!

 

 

 

 

 

 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM