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

Depth Texture の使用

各ピクセルに高精度の デプス 値を含む レンダーテクスチャ を作成することは可能です。これは主に、シーンのデプスを必要とするエフェクトに使用されます (例えば、ソフトパーティクル、スクリーンスペースのアンビエントオクルージョン、半透明のシーンにはシーンのデプスが必要です)。 イメージエフェクト も、しばしばデプステクスチャを使用します。

デプステクスチャのピクセル値は、線形でない分布を示し、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
カメラの深度テクスチャ