Unity 6 URPのAdaptive Probe Volumes 完全解説

シーンに配置した数百個のLight Probe Groupが엉뚱한場所を照らしているのに気づいたことはありませんか?オブジェクトの境界で照明が急に飛んだり、マルチシーンプロジェクトでベイクしたライティングがうまく馴染まず、手作業で配置を調整し続けた経験。まさにその問題を解決するために、Unity 6のURPに正式導入されたのがAdaptive Probe Volumes(APV)です。

HDRPで実験的に始まったAPVが、Unity 6.0(URP 17)でURPの安定版として搭載されました。この記事では、APVが既存のLight Probe Groupsと何が違うのか、内部でどのような仕組みで動くのか、そしてUnity 6.0から6.3 LTSにかけてどのような機能が追加されたのかを掘り下げます。


目次


Light Probe Groupsの限界 — なぜ新しいシステムが必要だったのか

従来のLight Probe Groups(LPG)は、開発者がシーン内に直接Light Probeを配置する方式でした。直感的ではありますが、規模が大きくなるにつれて3つの構造的な限界が露呈します。

第一に、per-objectサンプリング。 LPGはオブジェクト単位で1つのブレンドされたプローブ値を計算します。車のような大きなオブジェクトでは、ルーフが直射日光を受けていても、床と同じ暗い値を受け取ってしまいます。オブジェクトが複数の照明環境にまたがっている場合は、不正確なブレンディングが生じます。

第二に、手動配置の限界。 何千ものオブジェクトがあるシーンで、照明変化が多い領域(窓の近く、アーチの内側など)に適切にプローブを配置するのは、実質的に手作業です。配置が雑だと、境界に照明のつなぎ目(シーム)が生じます。

第三に、マルチシーンの限界。 複数のシーンを加算ロードする大規模なオープンワールドでは、LPGのベイクデータはシーン間の連続性を保証できません。

APVはこの3つすべてを、自動化と構造的な改善によって解決します。


APVのコアアイデア — 自動配置、ブリック構造、per-pixelサンプリング

APVの核心は3つです:自動配置ブリック構造per-pixelサンプリング

自動配置

LPGでは開発者がシーンを歩き回りながら手動でLight Probeを置く必要がありました。APVはこのプロセスを完全に自動化します。

ベイク前に、Unityはシーン内のMesh RendererとTerrainのうちContribute Global Illuminationが有効なオブジェクトをすべて収集し、ジオメトリ密度を解析します。この解析結果に基づき、オブジェクトが密集している領域にはプローブを細かく、空き空間には粗く配置します。

密度を手動で調整したい場合は2つの方法があります。APV InspectorのOverride Probe Spacingでシーン全体の最小・最大間隔を指定するか、特定の領域にローカルAPVボリュームを追加してその領域だけ別の間隔で制御できます。たとえば広い広場にローカルAPVをかぶせ、その区域だけ密度を下げるといった使い方です。

APV 自動配置

ブリック構造

Unityはシーンを解析し、ブリック(Brick)単位でLight Probeを自動配置します。ブリック1つは4×4×4の配列、つまり64個のLight Probeで構成されます。ブリックのサイズは固定ではなく、シーンのジオメトリ密度に応じて変化します。

APV ブリック構造

ブリック間隔のデフォルト: 1m / 3m / 9m / 27m(階層的に適用)

[複雑なジオメトリ領域]   → 1m間隔の小ブリック → 高解像度照明
[開けた空き空間]         → 27m間隔の大ブリック → メモリ節約

建物の内部や窓の近くなど照明変化が大きい領域は小さなブリックで細かく、開けた空の下の平野は大きなブリックで粗くカバーします。

per-pixelサンプリング

LPGとの最大の違いです。APVはオブジェクトごとに1つのプローブ値を使うのではなく、ピクセルごとに最も近い8つのプローブから照明データをサンプリングします。

LPG(従来):
車両 → 単一ブレンド値 → ルーフ/ボンネット/床すべて同一照明

APV(新方式):
車両ルーフのピクセル → 周辺8プローブをサンプリング → 直射日光を反映
車両床のピクセル     → 周辺8プローブをサンプリング → 地面の反射を反映

結果として、1つのオブジェクト内でも照明が自然に変化します。ボリューメトリックフォグを使用している場合、フォグ内部の照明変化もより正確に表現されます。

Per-object vs Per-pixelの比較


内部動作の仕組み — ベイクからランタイムストリーミングまで

APVはエディタのベイクフェーズとランタイムフェーズが明確に分離されています。

ベイクフェーズ

APVはシーンのジオメトリを解析してブリック配置を決定した後、Progressive GPU Lightmapperで各プローブ位置のSH(Spherical Harmonics)係数を計算して保存します。結果はBaking Set単位で管理されます。

Virtual Offsetという機能もあり、壁の内側や表面に近すぎるプローブを自動的に外側へ押し出してアーティファクトを軽減します。このプロセスも自動で処理されます。

ランタイムフェーズ

ランタイムでのAPVデータは4段階で処理されます:

1. Cell Registration  — セル(ブリックのグループ)をProbeReferenceVolumeに登録
2. Cell Streaming     — カメラ位置基準で近いセルを優先して非同期ロード
3. GPU Data Upload    — セルデータをテクスチャベース形式でGPUメモリにアップロード
4. Shader Sampling    — シェーダーがAPVResources構造体を通じてGIデータを参照

中核クラスはProbeReferenceVolumeシングルトンで、APVシステム全体を管理します。ProbeBrickPoolがGPUメモリのブリックデータを、ProbeBrickIndexが階層的なインデキシングと検索を担います。

ストリーミングシステムはカメラからの距離に基づいてセルの優先度を決め、限られたGPUメモリをプール方式で再利用します。この構造により、GPUメモリより大きなAPVデータもランタイムで分割ロードできます。


Sky Occlusion — 1回のベイクで空の色に基づく昼夜切り替えを実現

APVの中でも特に印象的な機能の1つです。Sky Occlusionは1回のベイクだけで、ambient probeから来る空の色の変化をランタイムに反映します。太陽位置の移動やシーン内の照明オブジェクトの状態変化はこの機能の範囲外ですが、空が明るくなったり暗くなったりする変化だけで十分な時間帯演出が可能な場合に有効な選択肢です。

動作原理

Sky Occlusionが有効になると、Unityはベイク時に各プローブにsky occlusion値を追加で保存します。この値は「このプローブ位置に空の光がどれくらい届くか」を表す静的データです。

ランタイムでGameObjectがプローブをサンプリングする際、Unityは2つの値を掛け合わせます:

最終的な空の光 = sky color(ambient probe、動的に更新)
              × sky occlusion value(ベイクされた静的値)

空の色はambient probeを通じてリアルタイムで変更できますが、どれだけ届くかはベイクされた値が決定します。建物の奥深くではsky occlusion値が低いため、空がどれだけ明るくても暗いままです。

有効化とランタイム設定

Sky Occlusionを使用するには、まずProgressive GPU Lightmapperに切り替える必要があります。CPU Lightmapperではsky occlusion計算自体がサポートされていません。

Window → Rendering → Lighting → SceneパネルLightmapper: Progressive GPUに変更し、APVパネルでSky Occlusionを有効にしてベイクを再実行します。

ランタイムで空の色を実際に変更するには、ambient probeが動的に更新される必要があります。URPでの方法は2つあります。

① Gradient / Color Sourceを使用(推奨)

Window → Rendering → Lighting → EnvironmentパネルSource: GradientまたはColorに設定します。その後RenderSettings.ambientSkyColorなどのAPIやAnimationウィンドウで色を変更すると、ambient probeに即座に反映されます。

② Skybox Sourceを使用(注意が必要)

SourceをSkyboxのままにすることもできますが、skyboxが変わるたびにDynamicGI.UpdateEnvironment()を手動で呼び出す必要があります。このAPIはパフォーマンス負荷が非常に高いため、時間帯システムのように毎フレーム色が変わる用途には適していません。

Sky Direction — 方向性のある空の光

基本的なSky Occlusionは空の光のしか保存しません。各ピクセルがambient probeをサンプリングする際の基準方向としてオブジェクトのサーフェス法線を使いますが、この近似は窓のある部屋の内部や洞窟の入口のように空の光が特定の方向からしか入らない状況では不正確になります。

Sky Directionを有効にすると、各プローブに空の光が実際に来る方向も一緒に保存します。バウンスライティングも考慮するため、洞窟や窓のあるシーンでは体感的な差が大きくなります。

APV - Sky Occlusion

ただし、プローブ間で方向データの補間が行われないため、プローブの境界でシームが生じる可能性があります。特定の領域の方向を手動で修正するには、Probe Adjustment Volumeコンポーネントをその領域に追加します。Sky Direction有効化時はベイク時間とランタイムメモリも追加で増加します。

Sky Occlusionの制限事項

制約 理由
Progressive GPU Lightmapper必須 CPU Lightmapperはsky occlusion計算に未対応
オブジェクトの色を無視 ベイク時にすべての表面を不透明なグレーとして処理 — 暗い壁も明るい壁も同量の光を反射
透明・半透明オブジェクト 窓や葉が光を透過せず不透明体として反射
Sky Direction のプローブ間補間なし 方向データが補間されないため、境界でシームが発生する可能性あり
ベイク時間・メモリの増加 sky occlusion値とSky Direction方向データの追加保存コスト

透明・半透明オブジェクトが多い場合、そのオブジェクトのStatic Editor FlagsでContribute GIを無効にするのが最も直接的な改善方法です。表面色の近似誤差を減らすには、APVパネルのSky Occlusion SettingsのAlbedo Override値を調整します。


Lighting Scenarios — より複雑な照明変化への対応

Sky Occlusionが空の色の変化に特化しているのに対し、Lighting Scenariosはシーン内の照明オブジェクトの状態変化(点灯中のランプ→消灯、昼の風景→夜の風景)にも対応します。

各Lighting Scenarioは特定の照明状態でベイクされたAPVデータセットです。ランタイムでシナリオを切り替えたり、2つのシナリオ間をブレンドしたりすることができます。Unity 6.0でURPにLighting Scenario Blendingが追加されました。

Sky Occlusion vs Lighting Scenariosの比較

項目 Sky Occlusion Lighting Scenarios
ベイク回数 1回 シナリオごとに1回
空の色の更新 動的(リアルタイム) 動的(リアルタイム)
シーン内照明変化 不可 可能
切り替えコスト 低(スムーズで高速) ブレンディングコストあり
精度 近似値 高い

両方を組み合わせて使うこともできます。Sky Occlusionで空の光の変化を処理し、Lighting Scenariosで室内照明の状態切り替えを処理するといった使い方です。

実務上の判断基準: 昼夜の切り替えだけが必要なら、Sky Occlusion単体で十分です。建物内の照明のオン/オフまで表現する必要があるならLighting Scenariosを追加してください。


大規模ワールドのためのDisk Streaming

大規模なオープンワールドで、APVデータ全体をメモリに読み込むのは現実的ではありません。Unity 6.0で追加されたDisk Streamingがこの問題を解決します。

ストリーミングが有効になると、APVデータはシーンを構成するセル(Cell)単位に分割してディスクに保存されます。ランタイムではカメラのビューフラスタム内にあるセルだけを非同期でロードします。

デフォルトではAPVデータはStreaming Assetsに保存されますが、Unity 6.0でProbe Volume Disable Streaming Assetsオプションが追加され、通常のアセット形式で保存できるようになりました。これにより、APVデータをAssetBundleやAddressablesに含めて配布することが可能になりました。

Project Settings > Graphics > Pipeline Specific Settings > URP > Adaptive Probe Volumes > Probe Volume Disable Streaming Assets


有効化の手順(URP基準)

3か所の設定が必要です。

① URP AssetでLight Probe Systemを変更
Project Settings > Quality → アクティブなURP Assetをダブルクリック
Lighting > Light Probe Lighting > Light Probe SystemAdaptive Probe Volumes

② APVオブジェクトを配置
GameObject > Light > Adaptive Probe Volume
InspectorでMode → Global(シーン全体をカバー)

③ オブジェクトのGI設定
– 光を受けるオブジェクト:Contribute Global Illuminationを有効化
Receive Global IlluminationLight Probes
– シーンに含める照明:Light > ModeMixedまたはBaked

設定後、Window > Rendering > LightingパネルでGenerate Lightingをクリック。


動作しない場合 — 制約事項とその理由

グラフィクスAPI/ハードウェア制約

APVのランタイムストリーミング、Sky Occlusionベイキングなどのコア機能は内部的にCompute Shaderを使用します。Compute Shaderに対応していないプラットフォームやグラフィクスAPIでは、APV自体が動作しません。

プラットフォーム / API Compute Shader APVサポート
DirectX 11/12(Shader Model 5.0以上) 完全対応 対応
Vulkan 完全対応 対応
Metal(iOS、macOS) 完全対応 対応
OpenGL ES 3.1(Android) 対応、ただしCompute Buffer 4個のみ保証 条件付き対応
OpenGL ES 3.0以下 Compute Shader非対応 非対応
OpenGL(macOS) Appleが4.1に制限 → Compute Shader非対応 非対応(Metalを使用のこと)
WebGL 2 Compute Shader非対応 非対応
WebGPU(実験的) Compute Shader対応だが制限あり 非対応(プロダクション非推奨)

OpenGL ES 3.1の注意点: スペック上Compute Bufferは4個のみ保証されています。実際のデバイスはより多くをサポートする場合が多いですが、古いAndroid低スペック端末をターゲットにする場合はSystemInfo.supportsComputeShadersでランタイムに確認するのが安全です。

macOSの注意点: AppleはmacOSでOpenGLを4.1に制限しているため、OpenGL経由でのCompute Shaderは使えません。macOSでAPVを使うにはグラフィクスAPIをMetalに設定する必要があります。

Sky Occlusionの追加制約: Sky OcclusionベイキングはProgressive GPU Lightmapperを使用するため、十分なVRAMがない環境ではベイキングがCPUにフォールバックし、Sky Occlusionは無効化されます。


シーン構造 / 機能制約

制約事項 理由
Light Probe Groupsとの同時使用は非推奨 1つのシーンで両システムが競合し、予測不能な照明結果が生じる
プローブ位置の手動調整不可 ブリック単位の自動配置構造のため、個別プローブ位置の編集インターフェースは提供されない
Light Probe Groupsからの変換不可 データ構造が根本的に異なるため、新規ベイクが必要
Sky Occlusionでの透明オブジェクト処理 ベイク時にすべての表面を不透明なグレーとして処理する近似方式の限界
LPPV(Light Probe Proxy Volume)とGPU Resident Drawer GPU Resident DrawerはインスタンスデータをGPUメモリに保持しCPU介入なしで処理するが、LPPVは毎フレームCPUがインスタンスごとのSH係数を注入する必要があり構造的に衝突。APV + GPU Resident Drawerの組み合わせを使う場合はLPPVの代わりにAPVを直接使用することを推奨

バージョン別変更履歴 — Unity 6.0 → 6.3 LTS

Unityバージョン URPバージョン 主なAPV変更点
6.0 URP 17 Lighting Scenario Blending、Sky Occlusion、Disk Streaming、AssetBundle/Addressables対応
6.1 URP 17.1 Bicubic Lightmap Sampling、Probe Atlas Blending制御の追加
6.2 URP 17.2 マルチシーン環境でのエディタメモリバグ修正、WebGL非対応エラーメッセージの追加、Addressablesエラーメッセージ改善
6.3 LTS URP 17.3 エディタメモリ・安定性の追加修正

Unity 6.0(URP 17) — コア機能の導入

HDRPで実験的に開発されていたAPVが、URPに安定版として正式導入されたタイミングです。Unity 2022 LTSで「URP does not support APV」というエラーを見たことがあるなら、その壁がUnity 6.0で取り払われたことになります。

このリリースでLighting Scenario Blending、Sky Occlusion、Disk Streamingが一度に導入されました。APVのコア機能のほとんどがこのバージョンで揃いました。

Unity 6.1(URP 17.1) — 品質改善

Bicubic Lightmap Samplingが追加されました。低解像度ライトマップでバイリニア補間によって生じる階段状のアーティファクトをBicubic方式で大幅に改善します。Project Settings > Graphics > Use Bicubic Lightmap Samplingで有効化できます。

Probe Atlas Blendingプロパティが追加され、Forward+レンダラーでReflection Probeアトラスブレンディングを独立して制御できるようになりました。

Unity 6.2 / 6.3 LTS — 安定化

両バージョンとも主にバグ修正に集中しています。特にマルチシーン環境でエディタメモリが過剰に増加するバグが修正されました。APVを使用するシーンが多いプロジェクトでエディタが重くなっていた場合、6.2以降へのアップグレードが有効です。

6.2ではWebGLビルド時のAPV非対応エラーが明示的に表示されるようになりました。以前はビルド途中で失敗したりランタイムエラーとしてのみ確認できる状態でした。


デバッグ — Rendering Debuggerの活用

APVが正常に動作しているか確認する主なツールはRendering Debuggerです。

Window > Analysis > Rendering Debugger > Probe Volumeタブ

オプション 確認できること
Display Probes 各プローブの位置と保存された照明データの可視化
Display Bricks ブリックの境界線を表示 — 密度分布の確認
Display Cells ストリーミング単位のセル境界を表示

ブリック密度が意図通りに分布していない場合は、Override Probe Spacingで特定領域の密度を直接指定するか、Probe Adjustment Volumeコンポーネントを追加して問題のある領域を細かく調整してください。


まとめ — 使うべき場面と慎重に検討すべき場面

APVが最も効果を発揮する条件:

  • 大規模シーンで何百ものLight Probeを手動で配置していたプロジェクト
  • オブジェクト境界での照明シームが目立つプロジェクト
  • ベイクされた間接光で時間帯演出を実装したい場合
  • オープンワールドのようにメモリを超える照明データをストリーミングで管理する必要がある場合

一方、慎重に検討すべきケース:

  • WebGLターゲットのプロジェクト:現時点では非対応
  • Sky Occlusion + 透明オブジェクトが多いシーン:窓や葉の透過光が重要な場合、近似値の誤差が目立つ可能性あり
  • 非常に小さなシーン:手動配置のLPGの方が直感的でコントロールしやすい場合あり

Unity 6.0でURPに初導入されて以来、6.3 LTSまで継続的に安定化が図られてきたAPVは、照明品質とワークフローの両面で、既存のLight Probe Groupsの有力な代替手段として定着しました。


参考資料

コメントする