[譯]Unity – Using Depth Textures

原文:Using Depth Textures

創建 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
    	}
	}
}

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s