創建 Render Textures 讓每個 pixel 都存有一個精準的 “depth" 值(參考 RenderTextureFormat.Depth) 是可能的。這通常被某些需要 depth 資訊的特效所使用(例如 soft particles, screen space ambient occlusion, translucency 都需要使用到場景的 depth)。
在 depth texture 裡的 pixel 值是非線性分布的,範圍介於 0~1 之間。精準度根據所使用的 depth buffer 決定,通常是 24 或 16 bits。當讀取 depth texture 時,會回傳一個高精度介於 0~1 之間的數值。如果你需要取得與 camera 之間的距離或是線性值的話,你需要手動計算。
在 Unity 裡的 depth texture 在不同平台有不同的執行方式。
- 在 Direct3D 9 (Windows),depth texture 會是 native depth buffer 或是一個 single channel 32 bit floating texture (“R32F" Direct3D 格式)。
○ 顯卡需要支援 native depth buffer (INTZ 格式)或是 floating point render textures 好讓他們運作。
○ 當繪製到 depth texture 時,fragment program 也必須輸出這個值。
○ 當讀取 depth texture 時,color 裡的 red 值會包含高精度的 depth 值。 - 在 OpenGL (Mac OS X),depth texture 是使用 native OpenGL depth texture (參考 ARB_depth_texture)。
○ 顯卡必須支援 OpenGL 1.4 或是 ARB_depth_texture 的衍伸。
○Depth texture 會對應到被繪製到 Z buffer 的內容,它不是使用來自 fragment program 的回傳值!
Using depth texture helper macros
Depth texture 大多是由 camera 繪製深度的。UnityCG.cginc 幫助文件裡有一些 macros 可以處理這裡遇到的繁雜過程:
- UNITY_TRANSFER_DEPTH(o): 計算 vertex 的 eye space depth 並輸出到 o (它應該要是一個 float2)。在 vertex program 要繪製 depth 時呼叫這個 macro。在 OpenGL 這個 macro 不會做任何事情,但是會偷偷地畫上 Z buffer 。
- UNITY_OUTPUT_DEPTH(i):從 i 回傳 eye space depth (它應該會是 float2)。 在 fragment program 要繪製 depth 時呼叫這個 macro。在 OpenGL 時,這個 macro 總是會回傳 zero,因為 depth 值會偷偷畫上Z buffer 。
- COMPUTE_EYEDEPTH(o):計算 vertex 的 eye space depth 並輸出到 o。當在 vertex program 裡面不想要把 depth 值塞入 depth texture時呼叫。
- DECODE_EYEDEPTH(i):給予一個來自 depth texture 的高精度值 i,回傳相應的 eye space depth 值。在 Direct3D 裡,這個 macro 就只是回傳 i * FarPlane。在 OpenGL 裡,它線性並延展來符合 camera 的 range。
舉例來說,這個 shader 會繪製物件的 depth:
Shader "Render Depth" { SubShader { Tags { "RenderType"="Opaque" } Pass { Fog { Mode Off } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos : SV_POSITION; float2 depth : TEXCOORD0; }; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); UNITY_TRANSFER_DEPTH(o.depth); return o; } half4 frag(v2f i) : COLOR { UNITY_OUTPUT_DEPTH(i.depth); } ENDCG } } }