Version: 2021.3
言語: 日本語
物理カメラの使用
カメラのトリック

カメラと深度テクスチャ

カメラ は、深度、深度 + 法線、またはモーションベクトルのテクスチャを生成できます。これは最低の G バッファテクスチャで、ポストプロセスエフェクトに使用されたり、カスタムライティングモデル (ライトプリパスなど) の実装に使用されます。

これらは主にエフェクトで使用されます。例えば、ポストプロセスエフェクト では、深度情報がよく使用されます。

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

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

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

カメラの深度テクスチャモードは、Camera.depthTextureMode 変数を使って、スクリプトから有効にすることができます。また、シェーダーの置き換え 機能を使って、同様のテクスチャを自身で作ることも可能です。

3 つの使用可能な深度テクスチャモードがあります。

  • DepthTextureMode.Depth - 深度テクスチャ。
  • DepthTextureMode.DepthNormals - 深度とビュー空間の法線を 1 まとめにしたテクスチャ。
  • DepthTextureMode.MotionVectors - 現在のフレームの各スクリーンテクセルのピクセルスクリーン空間のモーション。RG16 テクスチャにパックされます。

これらのフラグを使って、上記のテクスチャのどのような組み合わせも指定することができます。

DepthTextureMode.Depth テクスチャ

これは、画面サイズの深度テクスチャを作ります。

深度テクスチャは、シャドウキャスターのレンダリングに使用されるのと同じシェーダーパスを使用してレンダリングされます (ShadowCaster パスタイプ)。そのため、拡張機能により、シェーダーがシャドウキャスティング (影付け) をサポートしていない場合 (つまり、シェーダーかどのフォールバックにもシャドウキャスターのパスがない場合)、そのシェーダーを使用するオブジェクトは深度テクスチャに表示されません。

  • シャドウキャスティング (影付け) パスを持つ別のシェーダーに フォールバック させるか、あるいは、
  • サーフェスシェーダー を使用する場合は、ディレクティブ addshadow を加えることでシャドウパスを生成することが可能です。

マテリアルとシェーダーが レンダーキュー <= 2500 に設定されている不透明オブジェクトは、深度テクスチャにレンダリングされます。

DepthTextureMode.DepthNormals テクスチャ

これは画面サイズ 32 ビット (8 ビット/チャネル) テクスチャを作ります。ビュー空間法線が R と G チャネルに、深度が B と A チャネルにエンコードされます。法線は、ステレオ投影を使用してエンコードされ、深度は 16 ビットの値で、2 つの 8 ビットチャネルにパックされます。

UnityCG.cginc include ファイル にはヘルパー関数 DecodeDepthNormal があり、エンコードしたピクセルの値から深度と法線をデコードします。0 から 1 の範囲で深度を返します。

深度と法線のテクスチャの使用例については、ランタイムのシェーダーの置き換え または ポストプロセスと全画面エフェクト を参照してください。

DepthTextureMode.MotionVectors テクスチャ

これは、画面サイズ RG16 (16bit float/channel) のテククチャをビルドします。スクリーン空間のピクセルモーションは R&G channel にエンコードされます。ピクセルモーションはスクリーンの UV 空間でエンコードされます。

エンコードしたピクセルからテクスチャモーションをサンプリングすると、その範囲は –1 から 1 になります。これは以前のフレームから現在のフレームの UV の差を表します。

ヒントおよびテクニック

カメラが深度や深度や深度+法線のテクスチャをレンダリングする際に、Camera Inspector に表示されます。

深度テクスチャを必要とするエフェクトを無効にした後に Camera がまだそれをレンダリングしているという場合に、Camera (Camera.depthTextureMode) から深度テクスチャが要求されることがあります。それぞれが深度テクスチャを必要とする複数のエフェクトが Camera に存在する場合に、1 つのエフェクトを無効にするために自動的に深度テクスチャのレンダリングを無効にするよい方法はありません。

複雑なシェーダーやイメージエフェクトを実装するとき、プラットフォーム別のレンダリングの違い に注意してください。特に、イメージエフェクトで深度テクスチャを使用する場合は、Direct3D + アンチエイリアスの特別な処理が必要です。

ケースによっては深度テクスチャはネイティブの Z バッファから直接取得されている場合があります。もし深度テクスチャで画像の乱れがある場合、それを使用するシェーダーが Z バッファに 書き込まないように してください (ZWrite Off を使用してください)。

シェーダー変数

深度テクスチャは、グローバルシェーダープロパティとしてシェーダーでサンプリングすることができます。_CameraDepthTexture というサンプラーを宣言することによって、カメラの主要深度テクスチャをサンプリングすることができます。

_CameraDepthTexture は、常にカメラの最初の深度テクスチャを示します。反対に _LastCameraDepthTexture は、カメラに最後にレンダリングされた深度テクスチャを示します。例えば、スクリプトで解像度が半分の深度テクスチャを 2番目のカメラを使ってレンダリングし、ポストプロセスシェーダーに利用する場合に役に立ちます。

モーションベクトルテクスチャ (有効の場合) は、シェーダーでグローバルシェーダープロパティとして使用可能です。‘_CameraMotionVectorsTexture’ というサンプラーを宣言することによって、現在レンダリングしているカメラのテクスチャをサンプリングすることができます。

内部の処理

深度テクスチャは、使用されるレンダーパスやハードウェアに応じて、実際の深度バッファから直接取得されたり、別のパスにレンダリングされたりします。通常、ディファードシェーディングや古いディファードレンダーパスを使用する場合は、それらは G バッファのレンダリングによるものなので、深度テクスチャは “無料” で手に入ります。

DepthNormals テクスチャが別のパスにレンダリングされるとき、これは シェーダーの置き換え を通して行われます。したがってシェーダーで正しい “RenderType” タグを使用することが重要です。

使用可能な場合は、モーションベクトルのテクスチャは常に予備のレンダーパスから与えられます。Unity はこのバッファに動いているオブジェクトをレンダリングし、その動きを以前のフレームから現在のフレームに描画します。

物理カメラの使用
カメラのトリック