Skip to content

第09回 影表現の基礎

前回: 第08回 内積とフレネル、外積と法線マップ / 次回: 第10回 スキンメッシュ基礎

今回の授業内容

  • 影が空間認識とゲーム情報へ与える効果を理解する
  • Depth BufferとShadow Mapの役割を区別する
  • ライトから見た深度比較による影判定を理解する
  • Bias、Resolution、Shadow Distanceを比較する
  • Shader GraphのCast ShadowsとReceive Shadowsを確認する

影と深度の基礎

影が空間の関係を伝える

影があると、物体が床に接しているのか空中に浮いているのかが分かりやすくなります

影の向きから、ライトの位置や方向も推測できます

影の濃さ、ぼけ方、長さは、時間帯や空気感にも影響します

ゲームでは、リアルさだけでなくプレイヤーが足場、敵、攻撃範囲を読むための情報としても使われます

影は見た目の装飾ではなく、空間理解を助ける情報です

CastとReceive

役割意味
Cast Shadowほかの場所に影を落とす
Receive Shadowほかの物体からの影を受ける

影を落とす物体と、影を受ける物体は別の役割を持ちます

Unity では Mesh Renderer や Light、Render Pipeline の設定で影の有無や品質を調整します

「影が出ない」ときは、ライト、物体、マテリアル、Render Pipeline のどこで無効になっているかを切り分ける必要があります

リアルタイムで影を計算する難しさ

現実の影は、光が物体に遮られることで発生します
現実をそのまま再現するなら、光源から出る大量の光線を追跡し、 どこに届くかを調べる必要があります

しかし処理時間の限られたリアルタイム描画では、 毎フレームすべての光線を計算するのは現実的ではありません

そこでゲームでは、比較的軽く影を表現できる Shadow Map が広く使われています

カメラから見た奥行き

Z-depth map の例
Z-depth map の例この画像では、カメラに近いほど白く、 遠いほど黒く表示されている出典: Wikimedia Commons / Creativonly / Public domain

Depth は、カメラから見た奥行きを表す値です

3D空間の物体を画面に描くとき、 カメラに近い面は手前にあり、 カメラから遠い面は奥にいくことになります

奥にある面で手前の面を上書きしてしまうと 3D の描画は破綻してしまいます

そこで深度を比較して、カメラから見て手前にある面を優先して描画する仕組みが必要になります

ピクセルごとの奥行きを保存するDepth Buffer

Depth Buffer の概念図
画面上の重なりは、ピクセルごとの深度比較で解決される

Depth Bufferは、画面の各ピクセルに対応した深度を保存するバッファです

新しいピクセルを描画する際は、その深度をDepth Bufferに保存済みの深度と比較します

新しいピクセルの方が手前なら描画を行い、Depth Bufferも新しい深度に更新します

新しいピクセルのほうが奥なら、 既に描かれた手前の物体に隠れているため描画をスキップします

深度を比較・保存するZ TestとZ Write

深度比較は Z Test、深度を書き込む処理は Z Write と呼ばれます

一般的には、現在のピクセルが保存済みの深度より手前なら描画を行いますが、他の比較方法もあります

不透明オブジェクトでは通常 Z Write 有効で描画を行いますが、 半透明オブジェクトでは見た目の都合で無効にすることがあります

第04回で扱った透明表現の描画順問題は、Depth Bufferとも関係しています

Shadow Mapで影を判定する

ライトから深度を見る

通常のDepth Bufferは、カメラから見た奥行きを保存します

Shadow Map は、同じ考え方をライト視点に置き換えたものです
ライトから見て手前にある面には光が届き、 それより奥にある面は何かに遮られていると判断できます

つまりShadow Mapは、ライトから見たDepth Bufferのようなものです

ライトをカメラとして扱う

Shadow Map の深度ビュー
画像右上がライトから撮影された距離オブジェクト描画時にライト空間内の深度と比較してシャドウの有無を判定する

シャドウマップは、ライトから見たシーンの深度をテクスチャーとして保存したものです

ライトから見えている場所には光が届きますが物体に隠れている場所には光が届かないため影になります

「ライトから見て最初に見えた深度」と 「現在描画しているピクセルの深度」を比較することで、対象のピクセルが影になるかを判定できます

深度比較でライトから見えるかを調べる

Shadow Map には、ライトから見て最も手前にある面の深度が入ります

現在描画しているピクセルが、その深度より奥にある場合、 手前の物体に遮られていると判断できます

反対に、Shadow Map の深度と同じか手前であればライトから見えているので影にはなりません

判定は単純ですが、解像度や数値誤差による問題がつきもので安定した影を作るためには調整が必要になります

影用の情報を先に作る2パス描画

  1. ライトから見たシーンの深度だけを Shadow Map に保存する
  2. 通常のカメラからシーンを描画する
  3. 各ピクセルをライト空間に変換し、Shadow Map に保存された深度と比較する
  4. 奥にあれば、何かに遮られているので影として暗くする

この手順のためには 「ライトから見た深度を保存する描画パス」と 「カメラから描画する描画パス」の2つの描画パスが必要になります

ライト空間へ座標系をそろえる

カメラから描画しているピクセルの位置は、通常はワールド空間やクリップ空間などで扱われています

一方、Shadow Map はライトから見た深度なので、 比較するには現在ピクセルをライトから見た座標へ変換する必要があります

この「ライトから見た座標系」をライト空間と呼びます

ライト空間で見た深度を比較することで、 そのピクセルに光が届くかどうかを判定できます

影の品質を調整する

Shadow Acne

Shadow Map の深度はテクスチャーに保存されるため精度にも分解能にも限界があり、完全に連続した値にもなりません

現在描画している面と、Shadow Map に保存された面が同じでも、 数値誤差によって「少し奥にある」と判定されることがあります

その結果、本来影にならない表面にしま模様のような自己影が出ることがあります

この現象は Shadow Acne と呼ばれます Acne はニキビの意味で、表面に細かい影ができる様子から名付けられています

Shadow Bias

Bias が小さすぎる例
バイアスが小さすぎると精度エラーによる自己影が出る
Bias が大きすぎる例
バイアスが大きすぎると影が浮いて見える

Bias は、影判定で使う深度を少しずらし、 自己影が出にくくなるようにする値です

小さすぎると Shadow Acne が残ります

大きすぎると、影が物体から離れて見えます
この現象は Peter Panning と呼ばれます

影が汚い場合は、まず Bias と Normal Bias を少しずつ調整します

Normal Bias

Normal Bias は、影を落とす面を法線方向へ少し押し出すように扱う調整です

斜めの面や細かい形状では、通常の Bias だけでは自己影を消しにくいことがあります

Normal Bias を上げると Shadow Acne は減りますが、 細い影が消えたり、接地影が弱くなったりします

Bias 系の値は一般に「正解の数値」がありません
ライト、スケール、カメラ距離、解像度に合わせて都度調整が必要です

Shadow Resolution

Shadow Map はテクスチャーなので、解像度が足りないと影の輪郭がギザギザになります

解像度を上げると影は細かくなりますが、 メモリ使用量と描画負荷も上がります

影をきれいにしたいときは、ただ解像度を上げるだけでなくライトの範囲、Shadow Distance、カメラ距離も見直します

広い範囲を1枚の Shadow Map に詰め込むほど、 1ピクセルあたりの影の精度は下がります

Shadow Distance

Shadow Distance は、カメラからどの距離まで影を描くかを決める設定です

遠くまで影を描くほど、Shadow Map の限られた解像度を広い範囲に使うことになります

そのため Shadow Distance が長すぎると、 近くの影まで粗く見えることがあります

ゲームでは、遠くの影を省略したり、 距離に応じて品質を変えたりして負荷と見た目を調整します

ハードシャドウとソフトシャドウ

ハードシャドウの例
ソフトシャドウの例
ハードシャドウとソフトシャドウの比較

Hard Shadow は輪郭がくっきりした影 Soft Shadow は輪郭をぼかした影です

Shadow Map は「影か、影ではないか」の二値判定のため、通常は硬い影になります

Shadow Map を複数回サンプリングして周囲の結果を平均し、影の輪郭を柔らかくするのが Soft Shadow の一般的な実現方法です

サンプル数を増やすほど滑らかになりますが、 その分描画負荷も高くなります

Cascade Shadow

Cascade Shadow の設定
Cascade Shadow の解像度が低い例
Cascade Shadow の解像度を改善した例
カスケードシャドウの設定パネルと設定例シャドウマップ1枚では影が荒くなる

1枚の Shadow Map だけでは広範囲の影をフォローしきれず、近くの影が粗くなります

Cascade Shadow はカメラからの距離に応じて複数の Shadow Map を使い分ける方法です

近くは高精度、遠くは低精度にすることで見た目と負荷のバランスを取りやすくなります

ただしカスケードの境界が見えることもあるため、分割数や距離の調整が必要になります

Contact Shadow

Contact Shadow 調整前
Contact Shadow 調整後
SSAOでの影の強化例接地感が増す

Shadow Map の解像度や距離の制限で接地影が十分に表現できない場合の補強手法です

Unity の URP では未対応ですが、SSAO で似た効果を実現できます

実在感を強化する強力な手法ですが、 強すぎるとノイズ感が出て不自然になるため調整が必要です

Shader Graphと影

影を受ける設定と落とす設定

Lit 系の Shader Graph では、レンダーパイプラインのライト計算により影を受けることができます Unlit 系では、基本的にライトや影の影響を受けません

影を落とすかどうかは、シェーダーだけでなく Renderer の Cast Shadows 設定にも関係します

透明や Alpha Clip を使うマテリアルでは、 影の形もアルファに合わせたいのかを確認する必要があります

Alpha Clipを影へ反映する

葉っぱやフェンスのようなマテリアルでは、 四角いポリゴン全体ではなく、アルファで切り抜いた形の影が必要です

Alpha Clip を使うと、一定以下のアルファを描画しないため、 影用の描画でも切り抜き形状に近い影を作れます

しきい値が高すぎると影が欠けたり細くなったりし、 低すぎると本来透明にしたい部分まで影が残ります

第04回で扱った透明表現は、影の見え方にも関係します

法線マップと影の違い

法線マップは、ライティングに使う法線方向を変える技術です

しかし実際のメッシュ形状を変えているわけではないため、 法線マップの細かな凹凸そのものが Shadow Map に影を落とすわけではありません

近くで見る細かな陰影は法線マップで表現し、 大きな遮蔽や接地影は Shadow Map で表現します

必要に応じて、Height Map、Parallax、Displacement などの表現も使い分けます

実習:影の設定を確認する

影が出る条件と品質調整を試す

実習1:影が出る最小構成を作る

  1. 床用の Plane と、影を落とす Cube または Sphere を配置する
  2. Directional Light を配置する
  3. オブジェクトの Mesh Renderer で Cast Shadows を確認する
  4. 床側の Renderer とマテリアルが影を受ける設定になっているか確認する
  5. ライトの向きを変え、影の方向が変わることを確認する

実習2:Biasを調整する

  1. ライトの Shadow 設定を開く
  2. Bias を小さくして Shadow Acne が出るか確認する
  3. Bias を大きくして影が物体から離れるか確認する
  4. Normal Bias を調整して、斜めの面の自己影がどう変わるか確認する
  5. 不自然にならない範囲を探す

実習3:Shadow DistanceとResolutionを比較する

  1. カメラの近くと遠くにオブジェクトを配置する
  2. Shadow Distance を短くして、遠くの影が消えることを確認する
  3. Shadow Distance を長くして、近くの影の精度が変わるか確認する
  4. Shadow Resolution を変更して、輪郭のギザギザを比較する
  5. 見た目と負荷のバランスを考える

実習4:Alpha Clipの影を確認する

  1. 葉っぱやフェンスのようなアルファ付きテクスチャーを用意する
  2. Shader Graph で Alpha Clip を有効にする
  3. しきい値をプロパティ化する
  4. 表示される形と影の形が一致するか確認する
  5. しきい値を変えて、見た目と影がどう変わるか観察する

授業内課題:接地感のある影を作る

より良いビジュアルを作ってね

完成条件

  • 影を落とすオブジェクトと、影を受ける床または壁がある
  • Directional Light、Point Light、Spot Light のいずれかで影を出している
  • Bias または Normal Bias を調整し、極端な自己影や影の浮きを避けている
  • Shadow Distance または Shadow Resolution を変更して比較している
  • Alpha Clip を使う場合は、切り抜き形状に近い影になっている
  • スクリーンショットで、影による接地感が確認できる

確認項目

  • Cast Shadow と Receive Shadow の違いを説明できる
  • Shadow Map がライトから見た深度テクスチャーであることを説明できる
  • ライト空間での深度比較によって影を判定する考え方を説明できる
  • Shadow Acne、Peter Panning、Bias の関係を説明できる
  • Shadow Distance、Resolution、Cascade が影の品質に与える影響を説明できる

今回のまとめ

  • Shadow Map は、ライトから見たシーンの深度を保存したテクスチャーです
  • カメラから描画するときに、現在ピクセルのライト空間深度と Shadow Map の深度を比較して影を判定します
  • Shadow Map は近似なので、Bias、Resolution、Shadow Distance の調整が必要です
  • ソフトシャドウは、影判定を複数回サンプリングして輪郭を柔らかく見せる考え方です
  • 影は質感だけでなく、物体の位置関係と接地感を伝える重要な表現です