Version: 2020.1
言語: 日本語
カスタムシェーダー GUI
カメラの深度テクスチャ

Depth Texture の使用

It is possible to create Render Textures where each pixel contains a high-precision Depth value. This is mostly used when some effects need the Scene’s Depth to be available (for example, soft particles, screen space ambient occlusion and translucency would all need the Scene’s Depth). Image Effects often use Depth Textures, too.

デプステクスチャのピクセル値は、線形でない分布を示し、0 から 1 までの範囲です。使用される設定とプラットフォームによって、一般に精度は 32 ビットか 16 ビットです。デプステクスチャから読み込みするときは、0 から 1 の範囲の高精度の値が戻されます。もしカメラからの距離、あるいは、線形の 0 から 1 までの値を取得する必要がある場合、ヘルパーのマクロ(以下を参照)を使って、それを手動で計算する必要があります。

深度テクスチャは、現段階で一般的に使用されている多くのハードウェアとグラフィックス API でサポートされています。以下は特別な仕様のリストです。

  • Direct3D 11 以降 (Windows)、OpenGL 3 以降 (Mac/Linux)、OpenGL ES 3.0 以降 (iOS/Android)、Metal (iOS) や、PS4/XboxOne のようなコンソールはすべて、深度テクスチャに対応しています。
  • OpenGL ES 2.0 (iOS/Android) は GL_OES_depth_texture の拡張が必要です。
  • WebGL は WEBGL_depth_texture 拡張が必要です。

デプステクスチャシェーダーヘルパーのマクロ

ほとんどの場合デプステクスチャはカメラからのデプスをレンダリングするのに使用されます。内蔵のシェーダー include ファイル には上記の複雑さに対応するためのマクロが含まれています。

  • UNITY_TRANSFER_DEPTH(o): これは頂点の Eye Space Depth (視点空間深度)を計算し、o ( float2 であることが必須) に出力します。深度テクスチャに対してレンダリングするときに頂点プログラムで使用してください。ネイティブ深度テクスチャのあるプラットフォームでは、Z バッファの値は暗黙的にレンダリングされるため、このマクロは何もしません。
  • UNITY_OUTPUT_DEPTH(i): これは頂点の Eye Space Depth を i (float2 であることが必須)から戻します。深度テクスチャに対してレンダリングするときに、フラグメントプログラムで使用してください。ネイティブ深度テクスチャのあるプラットフォームではこのマクロは、Z バッファ値が暗黙的にレンダリングされるため、常に 0 を戻します。
  • COMPUTE_EYEDEPTH(i): これは頂点の Eye Space Depth を計算し、o に出力します。頂点プログラムで、深度テクスチャに レンダリングしない ときに、使用します。
  • DECODE_EYEDEPTH(i)/LinearEyeDepth(i): 深度テクスチャ i の高精度値を指定すると、対応する Eye Space Depth を返します。
  • Linear01Depth(i): 深度テクスチャ i の高精度値を指定すると、対応する 0 と 1 の間の範囲の直線深度を返します。

ノート: DX11/12、PS4、XboxOne、Metal では、Z バッファの範囲は 1 から 0、UNITY_REVERSED_Z は定義されます。他のプラットフォームでは、範囲は 0 から 1 です。

例えば、このシェーダーはオブジェクトの深度をレンダリングします。

Shader "Render Depth" {
    SubShader {
        Tags { "RenderType"="Opaque" }
        Pass {
            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 = UnityObjectToClipPos(v.vertex);
                UNITY_TRANSFER_DEPTH(o.depth);
                return o;
            }

            half4 frag(v2f i) : SV_Target {
                UNITY_OUTPUT_DEPTH(i.depth);
            }
            ENDCG
        }
    }
}

参照

カスタムシェーダー GUI
カメラの深度テクスチャ