LightEffect(プログラマ向け資料) - LHYAYOI/HujiTV GitHub Wiki

目次

  1. LightShaft取り扱い注意点
  2. デバッグ手順
  3. コードの対応表
  4. 描画と選別の仕組み
  5. 変更時の注意

1. StartUp

  • Direction/SpotLightのみ対応の個別にボリュームを付与するスクリプトを作成

RendererにVolumetricLightShaftFeatureを追加しないと動作しないから注意!

2. Debug

1. まず基本設定を確認

  • 使用中のCameraが参照する3D Rendererに、有効なLightShaftFeatureとシェーダーがあるか
  • VolumeのLayer Mask、weight、Enable、Intensity、密度、Overrideが有効か。別Volumeに上書きされていないか
  • SpotはLightShaftEmitterが必要。空間God RayではURP Main Directional Lightを使い、太陽のEmitterは不要
  • 影にはLightとURPの双方の設定が必要。Shadow Distance外・カスケード境界・アトラス品質も確認
  • Scene/Gameのカメラ、Renderer指定、Quality設定が意図したものか

2. 選別とタイルを確認

Godray Tools → LightShaft → 品質とタイルのデバッグ(従来の Tools → Light Shaft → Quality Diagnostics も有効)を開きます

  1. Cameraを明示的に指定
  2. Spot/Fogの候補数と描画数を確認
  3. Selected volume gizmosで、選択された領域・Priority・フェード重みを確認。
  4. Tile debugをTotalCandidates / SpotCandidates / FogCandidatesへ切り替え

タイルは低解像度8×8ピクセル、数字はタイルで交差判定する候補数です
色は0=暗色、1=紫、2=青、3=緑、4〜5=黄、6〜9=橙、10以上=赤
全配置数、実際の散乱寄与数、GPU時間ではありません
投影境界ボックスを使うため、候補は保守的です、近クリップ面をまたぐ境界は全画面候補になります

デバッグ中は対象カメラのタイル生成を強制します
Profileには保存せず、Offまたはウィンドウ終了で解除します
体積散乱が有効なカメラが対象です。表示負荷を含むため、本計測ではオフにします

3. 時間蓄積の残像を調べる

Temporalは既定オフです、有効時はカメラ別のping-pong履歴を使い、代表散乱深度で再投影します。
履歴を3×3近傍の色範囲に制限し、深度不一致を棄却します

照明・霧・設定・選択フェード、カメラカット、投影・解像度の変化、長いフレーム間隔で履歴を無効化します
診断ウィンドウにAccumulatingまたはリセット理由が表示されます
カメラの微小な移動では再投影を継続します

独立した遮蔽物による影の変化をすべてCPUで追跡しているわけではありません
イベントが分かる場合はFeatureの ResetHistory(camera)、全カメラなら ResetHistory() を呼べます
比較時はTemporalをオフにし、単フレームの問題か履歴の問題かを分けます

履歴は1280×720・半解像度でカメラあたり約7.03 MiB
XRではTemporalとTileを使わず従来経路に戻り、整数ターゲット非対応環境ではTileを無効化します、検証済みのGPU環境はD3D12です。

4. 負荷を測る

診断ウィンドウでRecord pass timingsをオンにし、Unity ProfilerのGPU計測も有効にします
N/Aは未取得または未実行で、0 msではありません。値は直前に完了したフレームの呼び出し平均です   複数カメラでは混在するため、比較は1カメラで行います。

パス 内容
Atmosphere 霧+Spot+空間God Rayの積分。個別には分離できない
Composite 合成+根元/深度境界の追加計算
SkyMask / Radial / RadialFilter 画面God Ray
Temporal 履歴の再投影・混合
Tiles 候補ビットマスク生成

検証時はRTX 4060、1280×720、半解像度、50組で、根元補完ありの効果パス合計中央値がTileオフ0.573 ms/オン0.489 msでした
シーン全体のGPU時間ではなく、他環境の保証値でもありません

3. Code

基点は Assets/hatake/lightEffect/ です。

ファイル 役割
scripts/LightShaftFeature.cs 候補収集、シェーダーパラメーター、Render Graph、カメラ別状態
scripts/LightShaftVolume.cs 全体設定・品質・フェード・Temporal/TileのVolumeParameter
scripts/LightShaftEmitter.cs Lightに付ける散乱強度・Priority・影の指定
scripts/LocalFogVolume.cs Box/Sphere局所霧、減算領域、Sun Boost、アクティブリスト
scripts/ShaftSelection.cs 順位付け、固定枠、ヒステリシス、退場→入場フェード
shaders/ShaftIntervals.hlsl 視線と円錐・Box・Sphereの交差、区間のステップ分割
shaders/ShaftRaymarch.hlsl 霧・Spot・空間God Rayの積分、代表深度
shaders/ShaftComposite.hlsl 深度を使う合成と根元・境界補完
scripts/ShaftHistory.cs、shaders/ShaftTemporal.hlsl 履歴RTHandleと再投影
shaders/ShaftTiles.hlsl タイルの候補ビットマスク生成
scripts/ShaftTileDebug.cs、shaders/ShaftTileDebug.hlsl 一時的なカメラ指定、ヒートマップ・数字・グリッド
scripts/ShaftProfiling.cs、ShaftBenchmarkPath.cs GPU/CPUコマンド計測、固定カメラ経路
scripts/ShaftPerformanceDemo.cs 0〜50組の切替、固定経路反復、CSV
scripts/ShaftQualityPresets.cs デモとEditorで共通の品質設定

4. 描画と選別の仕組み

Featureは透明物の描画前に実行します
深度から不透明面までの積分区間を作り、最大距離で制限します
霧・Spot・空間God Rayを低解像度で積分し、深度を考慮してフル解像度に合成します
透明物を正確に透過・屈折する霧ではありません

画面God Rayは別方式です
空の遮蔽マスク→太陽方向の放射状積分→低解像度フィルタを使います
画面外の太陽や特定の世界座標の見せ場には空間God Rayを使います
Sun Boostは画面God Rayを局所的に切り抜く機能ではありません

候補は視錐台・描画距離で絞り、Priority × 寄与量 × 画面占有の近似 × 近接度で評価します
表示中の候補にはヒステリシスを加えます。遮蔽物に完全に隠れているかを厳密にCPU判定する方式ではありません

固定枠の旧演出を0までフェードアウトしてから次をフェードインします
既定0.35秒は片側の時間です
光柱から外れたLightも通常照明・影は描き続けるので、4灯制限がシーン全体のライト負荷を4灯相当にするわけではありません

5. 変更時の注意

  • 4/16の上限変更はC#配列、シェーダー配列、ビットマスク、ループ、検証を同時に更新します。
  • パス番号0〜6をFeatureと両Shaderで一致させます。新しいテクスチャ/バッファはRender Graphの依存関係に明示します。
  • SceneViewとGameの履歴・選別は独立させます。Feature破棄、履歴無効化、解像度変更でRTHandleを解放します。
  • Volumeの新規パラメーターをUIから変更するときは .Override() を使い、既存Profileでも反映させます。
  • 光柱のCookie投影、Point Light、透明物への厳密な霧、Froxel、ReSTIRは未実装です。XR・モバイル・Playerビルドの最終確認は別途必要です。
  • URP内部のSerializedProperty(RendererDataList、RendererFeatureMap、影設定)をセットアップで使用します。URP更新時はStage 7と対象カメラのRenderer割り当てを確認してください。

LightShaft Godray