カスタムシェーダー 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
カメラの深度テクスチャ