Shader 渲染佇列 ZWrite和ZTest

2021-07-25 16:25:44 字數 4853 閱讀 1329

本文**

僅供學習

(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來改變物體的遮擋關係!

測試環境(藍色方塊距離相機較近,注意這個不是game檢視):

測試的shader**(兩個方塊的shader**起始都是一樣的,測試時修改的是測試區里的**):

[csharp] view plain copy

shader 「custom/ztest」

} subshader

lod 200

/測試區

tags

//zwrite off

//ztest off

/測試區

cgprogram

#pragma su***ce surf lambert

sampler2d _maintex;  

struct input ;

void surf (input in, inout su***ceoutput o)

endcg

}

fallback "diffuse"

渲染順序:先藍色方塊再白色方塊(以下簡稱藍,白)

注意zwrite預設值為on,ztest預設值為lequal,沒有渲染物體時,深度快取中的深度可以理解為無限大

1. [csharp] view plain copy

/藍色方塊測試區

tags

zwrite off

//ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

//zwrite off

//ztest off

/白色方塊測試區

結果:白在前面

分析:藍沒有將畫素寫進深度快取中,ztest通過了,顏色快取中存放了藍的顏色值

白將畫素寫進深度快取中,ztest通過了,顏色快取的值變為白的,所以顯示白

2. [csharp] view plain copy

/藍色方塊測試區

tags

//zwrite off

//ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

//zwrite off

//ztest off

/白色方塊測試區

結果:藍在前面

分析:藍將畫素寫進深度快取中,ztest通過了,顏色快取中存放了藍的顏色值

而白的畫素深度大於藍的,既沒有成功將畫素寫進深度快取,同時ztest不通過,畫素被捨棄,所以顯示藍

3. [csharp] view plain copy

/藍色方塊測試區

tags

zwrite off

ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

//zwrite off

//ztest off

/白色方塊測試區

結果:白在前面

分析:藍沒有將畫素寫進深度快取中,ztest通過了,顏色快取中存放了藍的顏色值

白將畫素寫進深度快取中,ztest通過了,顏色快取中存放為白的顏色值

4. [csharp] view plain copy

/藍色方塊測試區

tags

//zwrite off

//ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

//zwrite off

ztest off

/白色方塊測試區

結果:白在前面

分析:藍將畫素寫進了深度快取中

白將畫素寫進了深度快取中,ztest通過了,白將顏色快取中的藍的畫素顏色值替換了。

5. [csharp] view plain copy

/藍色方塊測試區

tags

//zwrite off

//ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

zwrite off

ztest off

/白色方塊測試區

結果:白在前面

分析:藍將畫素寫進了深度快取中

白沒能將畫素寫進了深度快取中(zwrite為off),但ztest通過了,此時顏色快取的值變為白的,但是深度快取的值是藍的

6. [csharp] view plain copy

/藍色方塊測試區

tags

//zwrite off

ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

//zwrite off

ztest off

/白色方塊測試區

結果:白在前面

分析:藍將畫素寫進了深度快取中

白將畫素寫進了深度快取中,ztest通過了,此時顏色快取的值變為白的

7. [csharp] view plain copy

/藍色方塊測試區

tags

zwrite off

//ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

zwrite off

//ztest off

/白色方塊測試區

結果:白在前面

分析:白、藍都沒有將畫素寫入深度快取中,所以深度快取中的深度值為無窮大,最後因為白中ztest預設值的原因,所以顯示白

8. [csharp] view plain copy

/藍色方塊測試區

tags

zwrite off

ztest off

/藍色方塊測試區

[csharp] view plain copy

/白色方塊測試區

tags

zwrite off

ztest off

/白色方塊測試區

結果:白在前面

分析:與7類似

Shader的渲染佇列

首先看一下unity中的幾種內建的渲染佇列,按照渲染順序,從先到後進行排序,佇列數越小的,越先渲染,佇列數越大的,越後渲染。background 1000 最早被渲染的物體的佇列。geometry 2000 不透明物體的渲染佇列。大多數物體都應該使用該佇列進行渲染,也是unity shader中預設...

Shader渲染佇列數值範圍

渲染佇列 渲染佇列描述 渲染佇列值 background 這個佇列被最先渲染。它被用於skyboxes等。1000 geometry 這是預設的渲染佇列。它被用於絕大多數物件。不透明幾何體使用該佇列。2000 alphatest 通道檢查的幾何體使用該佇列。它和geometry佇列不同,對於在所有立...

Shader 渲染流程

gpu graphics processing unit,影象處理器,gpu上有成千上萬核,這些核並行執行 cpu central processing unit,處理器,cpu通常有單核 雙核 四核和八核,但這些核只能序列操作。渲染流水線的工作任務在於由乙個三維場景出發 生成 或渲染 一張二維影象...