2 / 4 ライトからの深度比較
影の判定に使う二つの深度を、同じ基準で比較します。
一つの比較例
ライトから見た一つの方向で、最初の面までの深度が3、調べる床までの深度が5だったとします。同じ基準で比較すると、床より手前に物体があるため、床はそのライトから遮られています。次の説明では「どこから見た深度か」を確認します。
カメラから見た奥行き

Z-depth mapの例です。この画像では、カメラに近いほど白く、遠いほど黒く表示されています。出典: Wikimedia Commons / Creativonly / Public domain。
Depth は、カメラから見た奥行きを表す値です。
3D空間の物体を画面に描くとき、 カメラに近い面は手前にあり、 カメラから遠い面は奥にいくことになります。
奥にある面で手前の面を上書きしてしまうと 3D の描画は破綻してしまいます。
そこで深度を比較して、カメラから見て手前にある面を優先して描画する仕組みが必要になります。
ピクセルごとの奥行きを保存するDepth Buffer
画面上の重なりは、ピクセルごとの深度比較で解決される。
Depth Bufferは、画面の各ピクセルに対応した深度を保存するバッファです。
新しいピクセルを描画する際は、その深度をDepth Bufferに保存済みの深度と比較します。
新しいピクセルの方が手前なら描画を行い、Depth Bufferも新しい深度に更新します。
新しいピクセルのほうが奥なら、 既に描かれた手前の物体に隠れているため描画をスキップします。
Shadow Mapで影を判定する
ライトから深度を見る
通常のDepth Bufferは、カメラから見た奥行きを保存します。
Shadow Map は、同じ考え方をライト視点に置き換えたものです。
ライトから見て手前にある面には光が届き、 それより奥にある面は何かに遮られていると判断できます。
つまりShadow Mapは、ライトから見たDepth Bufferのようなものです。
ライトをカメラとして扱う

画像右上は、ライトから見た深度を表しています。オブジェクトの描画時にライト空間で深度を比較し、影の有無を判定します。
シャドウマップは、ライトから見たシーンの深度をテクスチャーとして保存したものです。
ライトから見えている場所には光が届きますが物体に隠れている場所には光が届かないため影になります。
「ライトから見て最初に見えた深度」と 「現在描画しているピクセルの深度」を比較することで、対象のピクセルが影になるかを判定できます。
深度比較でライトから見えるかを調べる
Shadow Map には、ライトから見て最も手前にある面の深度が入ります。
現在描画しているピクセルが、その深度より奥にある場合、 手前の物体に遮られていると判断できます。
反対に、Shadow Map の深度と同じか手前であればライトから見えているので影にはなりません。
判定は単純ですが、解像度や数値誤差による問題がつきもので安定した影を作るためには調整が必要になります。
影用の情報を先に作る2パス描画
- ライトから見たシーンの深度だけを Shadow Map に保存する
- 通常のカメラからシーンを描画する
- 各ピクセルをライト空間に変換し、Shadow Map に保存された深度と比較する
- 奥にあれば、何かに遮られているので影として暗くする
この手順のためには 「ライトから見た深度を保存する描画パス」と 「カメラから描画する描画パス」の2つの描画パスが必要になります。
ライト空間へ座標系をそろえる
カメラから描画しているピクセルの位置は、通常はワールド空間やクリップ空間などで扱われています。
一方、Shadow Map はライトから見た深度なので、 比較するには現在ピクセルをライトから見た座標へ変換する必要があります。
この「ライトから見た座標系」をライト空間と呼びます。
ライト空間で見た深度を比較することで、 そのピクセルに光が届くかどうかを判定できます。
条件を変えた確認
最初の面と調べる面の深度がどちらも3ならどう判断しますか。Cameraからの深度5を、そのままライトからの深度3と比べてよいかも説明してください。
予測と結果の照合
同じ3なら遮る別の面は確認されません。異なる視点や投影の深度はそのまま比較できず、基準をそろえる必要があります。実際の比較では精度の誤差も扱います。
Sceneの設定は最初の状態を保ち、次のBias比較の基準にします。
- Shadow MapとCameraのDepth Bufferを区別できる。
- 同じ基準の二つの深度から遮蔽を説明できる。