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

Depth Texture の使用

各ピクセルが高い精度の デプス 値を持つ レンダーテクスチャ を作成することができます。主に使用されるのはエフェクトでシーンのデプスを使用する必要がある場合です (例えば、ソフトパーティクル、スクリーン空間環境光オクルージョン、透過はすべてシーンのデプスが必要です)。Image Effects もよくデプステクスチャを使用します。

デプステクスチャのピクセル値は、線形でない分布を示し、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 のようなコンソールでは、ネイティブデプステクスチャに対応しています。
  • Direct3D 9 (Windows) は “INTZ” テクスチャフォーマットに対応して、デプステクスチャを取得するには、グラフィックスドライバを必要とします。
  • 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(o): これは頂点の Eye Space Depth を計算し、__o__に出力します。頂点プログラムで、デプステクスチャに レンダリングしない ときに、使用します。
  • DECODE_EYEDEPTH(i): given high precision value from depth texture i, returns corresponding eye space depth. This macro just returns i*FarPlane on Direct3D. On platforms with native depth textures it linearizes and expands the value to match camera’s range. Note: On DX11/12, PS4, XboxOne and Metal, the Z buffer range is 1–0 and UNITY_REVERSED_Z is defined. On other platforms, the range is 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
カメラの深度テクスチャ