---
title: [Tokyo DevDays 26&#039;] MegaLights入門 - その仕組みと最適化方法について
tags:  #devdays #ue5  
author: [エピック ゲームズ ジャパン](https://www.docswell.com/user/EpicGamesJapan)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LE3WXR19E5.jpg?width=480
description: 2026年8月26日に開催されました「Unreal Engine Tokyo Dev Days 26&#039;」イベントの「MegaLights入門 - その仕組みと最適化方法について」講演のスライドです。
published: August 31, 26
canonical: https://www.docswell.com/s/EpicGamesJapan/Z27EW1-DayDays26-MegaLights
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LE3WXR19E5.jpg)

Mega Lights入門
その仕組みと最適化方法について
Epic Games Japan
Developer Relations, Software Engineer
澤田 祐太朗


# Page. 2

![Page Image](https://bcdn.docswell.com/page/8EDK2YX87G.jpg)

1ページで振り返るMegaLights
Production Ready
多数の影付きライトを効率的に処理
現世代コンソールで60 fpsをターゲット
1 フレームで1 ピクセルが評価するライト数を固定
MegaLights 有効化
おおよそ10 倍の高速化
影付きポイントライト 900 個のシーン
PC計測: 134 ms → 13 ms (シーンや条件による)


# Page. 3

![Page Image](https://bcdn.docswell.com/page/V7PK16PWJ8.jpg)

目次
●
4つの描画アーティファクト例
●
MegaLights の処理の流れ・設定
●
まとめ


# Page. 4

![Page Image](https://bcdn.docswell.com/page/2JVVY329JQ.jpg)

4つの描画アーティファクト例


# Page. 5

![Page Image](https://bcdn.docswell.com/page/5EGL93R4JL.jpg)

(1) 残像


# Page. 6

![Page Image](https://bcdn.docswell.com/page/4JQYW5VR7P.jpg)

TSRが原因？ ( r.AntiAliasingMethod 0 )


# Page. 7

![Page Image](https://bcdn.docswell.com/page/K74WK9MQE1.jpg)

影に発生しているノイズ


# Page. 8

![Page Image](https://bcdn.docswell.com/page/LJ1YXK8LEG.jpg)

再度TSRを有効化 ( r.AntiAliasingMethod 4 )


# Page. 9

![Page Image](https://bcdn.docswell.com/page/GJWGNDZQ72.jpg)

Temporal Filterを有効化


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4EZL3G1373.jpg)

(2) 影形状の例


# Page. 11

![Page Image](https://bcdn.docswell.com/page/Y76WXYLZ7V.jpg)

(2) 影形状の例


# Page. 12

![Page Image](https://bcdn.docswell.com/page/G75MXG1974.jpg)

近づいてみると・・・


# Page. 13

![Page Image](https://bcdn.docswell.com/page/9J29XY15ER.jpg)

Plane(板)にMaskedマテリアルを設定中


# Page. 14

![Page Image](https://bcdn.docswell.com/page/DEY48GZ6JM.jpg)

Maskedのテクスチャを外すと


# Page. 15

![Page Image](https://bcdn.docswell.com/page/VJNYQGY178.jpg)

ScreenTraceでMaskedの状態を切り抜いている


# Page. 16

![Page Image](https://bcdn.docswell.com/page/YE9PDWPYJ3.jpg)

r.MegaLights.ScreenTraces 0


# Page. 17

![Page Image](https://bcdn.docswell.com/page/GE8D3NDKED.jpg)

r.MegaLights.HardwareRayTracing.EvaluateMaterialMo
de 2


# Page. 18

![Page Image](https://bcdn.docswell.com/page/LELMVPMP7R.jpg)

ジオメトリに置き換え(Plane → Cylinder)


# Page. 19

![Page Image](https://bcdn.docswell.com/page/4JMYG4Y2JW.jpg)

(3) 影形状の例 - 薄いジオメトリ


# Page. 20

![Page Image](https://bcdn.docswell.com/page/PJR9ZW9579.jpg)

カメラを引いてみると...


# Page. 21

![Page Image](https://bcdn.docswell.com/page/PEXQ9PQXJX.jpg)

照明からの欠けている影


# Page. 22

![Page Image](https://bcdn.docswell.com/page/3EK9PD99ED.jpg)

照明カバーのジオメトリが薄い


# Page. 23

![Page Image](https://bcdn.docswell.com/page/L73WXRW975.jpg)

ScreenTrace 0


# Page. 24

![Page Image](https://bcdn.docswell.com/page/87DK2YK8JG.jpg)

ScreenTrace 1


# Page. 25

![Page Image](https://bcdn.docswell.com/page/VJPK16KWE8.jpg)

r.MegaLights.ScreenTraces.Quality 0


# Page. 26

![Page Image](https://bcdn.docswell.com/page/2EVVY3V9EQ.jpg)

Point Light → Spot Lightに置き換え


# Page. 27

![Page Image](https://bcdn.docswell.com/page/57GL93L4EL.jpg)

(4) 影形状 - ScreenTraceが助けてくれるケース


# Page. 28

![Page Image](https://bcdn.docswell.com/page/4EQYW5YRJP.jpg)

r.MegaLights.ScreenTraces 0


# Page. 29

![Page Image](https://bcdn.docswell.com/page/KJ4WK9WQ71.jpg)

違和感のある影


# Page. 30

![Page Image](https://bcdn.docswell.com/page/LE1YXKYL7G.jpg)

Shadow Casters View


# Page. 31

![Page Image](https://bcdn.docswell.com/page/GEWGNDGQJ2.jpg)

MegaLights - Overview


# Page. 32

![Page Image](https://bcdn.docswell.com/page/47ZL3GL3J3.jpg)

Overview - Shadow Casters


# Page. 33

![Page Image](https://bcdn.docswell.com/page/YJ6WXYWZJV.jpg)

MegaLights - Overview


# Page. 34

![Page Image](https://bcdn.docswell.com/page/GJ5MXGM9J4.jpg)

MegaLights - Overview


# Page. 35

![Page Image](https://bcdn.docswell.com/page/9E29XY957R.jpg)

Shadow Caster Quality


# Page. 36

![Page Image](https://bcdn.docswell.com/page/D7Y48G46EM.jpg)

MegaLights - Overview


# Page. 37

![Page Image](https://bcdn.docswell.com/page/VENYQG61J8.jpg)

MegaLights - Overview


# Page. 38

![Page Image](https://bcdn.docswell.com/page/Y79PDWLYE3.jpg)

ScreenTrace - Depthの利用


# Page. 39

![Page Image](https://bcdn.docswell.com/page/G78D3NXK7D.jpg)

組み合わせることで形状の差分を補正


# Page. 40

![Page Image](https://bcdn.docswell.com/page/L7LMVP8PJR.jpg)

4つの描画アーティファクト例


# Page. 41

![Page Image](https://bcdn.docswell.com/page/4EMYG462EW.jpg)

目次
●
4つの描画アーティファクト例
●
MegaLights の処理の流れと設定
●
まとめ


# Page. 42

![Page Image](https://bcdn.docswell.com/page/PER9ZWP5J9.jpg)

MegaLights - 有効化手順
・プロジェクト設定からMegaLights を有効化
・Hardware Ray Tracingのサポートを有効化
・ライト個別のオンオフはデフォルト有効化済み
Ray Tracing or VSM
r.MegaLights.DefaultShadowMethod =
&quot;0&quot;
(Raytracing)


# Page. 43

![Page Image](https://bcdn.docswell.com/page/P7XQ9P3XEX.jpg)

MegaLights オンオフで負荷を比較
MegaLightオフ
MegaLightオン
※VSMのキャッシュが効いた状態
Ryzen Threadripper PRO 3995WX
Geforce RTX 3080
MegaLightsオフだと約134ms
MegaLightsオンだと約13ms


# Page. 44

![Page Image](https://bcdn.docswell.com/page/37K9PDY97D.jpg)

従来のライティングと MegaLights の違い
従来：ライトごとに回す
MegaLights：ピクセルごとに固定本数
ライト 1
シャドウマップを描く → 適用
候補からサンプルを選ぶ（確率的）
ライト 2
シャドウマップを描く → 適用
選んだ分だけシャドウレイを飛ばす
ライト 3
シャドウマップを描く → 適用
シェーディング
⋮
ライトの数だけ繰り返す
デノイズ（時間＋空間）
コストはライト数に比例
コストはほぼ一定
ライトを増やすほど重くなる
ピクセル数 × サンプル数で決まる


# Page. 45

![Page Image](https://bcdn.docswell.com/page/LJ3WXR99J5.jpg)

1 フレームの中の MegaLights 固有のパス
MegaLights は 主に2つの地点で分かれて動作
PrePass
Nanite
BasePass
(GBuﬀer)
MegaLights①
ライトを選択
Shadow
Depths /
VSM
RenderLights
① どのライトへレイを飛ばすか決める
② 後半にトレース～デノイズ
MegaLights②
トレース～
デノイズ
Translucency
PostProcess


# Page. 46

![Page Image](https://bcdn.docswell.com/page/8JDK2YG8EG.jpg)

InsightsでみるMegaLightsの固有パス
①Base Pass 後にあるStochostics LighingとMegaLights パス
②ライティングパスを挟みもう一度 MegaLights パス


# Page. 47

![Page Image](https://bcdn.docswell.com/page/VEPK163W78.jpg)

詳細を見る場合- r.RHISetGPUCaptureOptions 1
GPU Insightsに情報を追加可能


# Page. 48

![Page Image](https://bcdn.docswell.com/page/27VVY3497Q.jpg)

r.RHISetGPUCaptureOptions 1で増える情報
Base Passなどで、
おおよそのマテリアル単位の負荷も確認可能


# Page. 49

![Page Image](https://bcdn.docswell.com/page/5JGL93147L.jpg)

詳細を見る場合- r.RHISetGPUCaptureOptions 1
GPU Insightsに情報を追加可能


# Page. 50

![Page Image](https://bcdn.docswell.com/page/47QYW5DREP.jpg)

MegaLights 内部のパス
① GenerateMegaLightsSamples()
TileClassiﬁcationMark
—— ShadowDepths の前
GenerateSamples
VolumeGenerateSamples
VirtualShadowMap
MarkLightSamples
② RenderMegaLights() —— RenderLights の後
CompactLightSample
Traces
VirtualShadowMap
TraceLightSamples
ScreenSpaceRayTrace
LightSamples
HardwareRayTrace
LightSamples
ShadeLightSamples
VisibleLightHash
Temporal Filter
Spatial Filter


# Page. 51

![Page Image](https://bcdn.docswell.com/page/KE4WK9ZQJ1.jpg)

MegaLightsパスの全体像
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 52

![Page Image](https://bcdn.docswell.com/page/L71YXKRLJG.jpg)

MegaLightsの全体像
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 53

![Page Image](https://bcdn.docswell.com/page/G7WGND1QE2.jpg)

Insightsで見るMegaLightsの関連パス


# Page. 54

![Page Image](https://bcdn.docswell.com/page/4JZL3GP3E3.jpg)

MegaLightsの全体像
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 55

![Page Image](https://bcdn.docswell.com/page/YE6WXYMZEV.jpg)

前半の処理
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
↓
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 56

![Page Image](https://bcdn.docswell.com/page/GE5MXGZ9E4.jpg)

処理の流れ (1) — ライトを選ぶ
① Light Grid
たくさんのライトをグリッドに追加、管理
② Tile Classiﬁcation
ダウンサンプルとタイル分類
③ GenerateLightSamples
Light Gridやタイルからライトを選ぶ
r.MegaLights.DownsampleMode = 2
r.MegaLights.NumSamplesPerPixel = 4
r.MegaLights.GuideByHistory = 1
r.MegaLights.LightAttenuationFalloﬀ = .18


# Page. 57

![Page Image](https://bcdn.docswell.com/page/9729XYR5JR.jpg)

Light Grid - ライトをグリッド上のセルに登録
セル毎のライト: r.Forward.MaxCulledLightsPerCell 32
64pxずつ:
r.Forward.LightGridPixelSize 64
Z方向のスライス: r.Forward.LightGridSizeZ 32
Camera
Z スライスは対数分布
手前が細かく遠方が粗い


# Page. 58

![Page Image](https://bcdn.docswell.com/page/DJY48GD67M.jpg)

MegaLights - 影付きポイントライト900個を配置
ライトの範囲は狭いものの数が多い


# Page. 59

![Page Image](https://bcdn.docswell.com/page/V7NYQGN1E8.jpg)

ライトが多い場合に、ブロックノイズが発生するケース


# Page. 60

![Page Image](https://bcdn.docswell.com/page/YJ9PDWRY73.jpg)

LightGridの設定数が足りていない


# Page. 61

![Page Image](https://bcdn.docswell.com/page/GJ8D3NWKJD.jpg)

Light Grid Debug
r.Forward.LightGridDebug 1


# Page. 62

![Page Image](https://bcdn.docswell.com/page/LJLMVPNPER.jpg)

LightLinkedListCulling モードで実質プール管理に
デフォルト
r.Forward.LightLinkedListCulling 1
グローバルプール =
MaxCulledLightsPerCell * LightGridSizeZ
* ( X / LightGridPixelSize) * ( Y / LightGridPixelSize) * 2
(最後の2はReﬂectionCapture用の分)
Camera


# Page. 63

![Page Image](https://bcdn.docswell.com/page/47MYG4X27W.jpg)

LightLinkedListCulling モードで実質プール管理に
(1920 / 64 ) × (1080 / 64) × 32 × 32 × 2 = 1,044,480
約104万のエントリ
「104万エントリ」は&quot;ライトの数&quot;ではなく&quot;ライトとセルの重なりの総数&quot;。
ライトが密集し、かつカメラに近いほど、
1個のライトが多数のセルに重複登録されるため注意が必要
Camera
そして
→利用する際には描画箇所のセルのライトのみが参照される


# Page. 64

![Page Image](https://bcdn.docswell.com/page/P7R9ZWN5E9.jpg)

ライトが多い場合に、ブロックノイズが発生するケース


# Page. 65

![Page Image](https://bcdn.docswell.com/page/PJXQ9PNX7X.jpg)

MegaLights - Light Complexity


# Page. 66

![Page Image](https://bcdn.docswell.com/page/3JK9PDN9JD.jpg)

候補数が多い箇所ほど赤くなる


# Page. 67

![Page Image](https://bcdn.docswell.com/page/LE3WXRV9E5.jpg)

マウスカーソルによるデバッグ


# Page. 68

![Page Image](https://bcdn.docswell.com/page/8EDK2Y887G.jpg)

評価されるライトの候補、確率、可視状態、種類


# Page. 69

![Page Image](https://bcdn.docswell.com/page/V7PK168WJ8.jpg)

Tile Classiﬁcation — 8×8 pixタイルでスクリーンを分割
8×8 のタイル単位で処理を分類する
→ 後段は各タイルで必要な処理だけを実行できる


# Page. 70

![Page Image](https://bcdn.docswell.com/page/2JVVY3N9JQ.jpg)

タイル種別
軸A
マテリアルの複雑さ
Simple
軸B
そのタイルに掛かるライトの種類
Default Lit
通常(無印)
Single
Cloth／Subsurface／Clear coat
Complex
×
Rect
ポイント・スポット
そのセルに Rect ライトがある
Aniso/Hair/Eye
Rect Textured
Complex Special
Rect ライトテクスチャ付き
Glints
Empty
対象ピクセルなし → 実行しない
最大 13 種のタイルモードになる
種別ごとにシェーダを用意して処理を削減(タイルに複数の対象がある場合重いものが選択される)


# Page. 71

![Page Image](https://bcdn.docswell.com/page/5EGL93K4JL.jpg)

r.MegaLights.Visualize.TileClassiﬁcation 2
Simple
Single
Default Lit
Cloth／Subsurface／Clear coat
Complex
Aniso/Hair/Eye
Complex Special
Glints


# Page. 72

![Page Image](https://bcdn.docswell.com/page/4JQYW5NR7P.jpg)

GenerateLightSamples - 候補ライトが選ばれるまで
シーン内の全ライト 数百～数千個
Light Grid のセルで絞る
EstimateLocalLight
しきい値未満は除外
GetLocalLightTargetPDF で重み計算
影なしのシェーディングを 1 回実行
AddLightSample
評価するライトを確定
選ばれなかったライトの分は
重み = WeightSum / 自分の重み
で補正される
最終的にレイを飛ばすのはデフォルト4つだけ


# Page. 73

![Page Image](https://bcdn.docswell.com/page/K74WK9GQE1.jpg)

EstimateLocalLight — 簡易的な判定で外す
候補の中で「まず捨てる」ための粗い見積もり、
距離と減衰しか見ないため非常に軽い
しきい値未満なら、後段の重い GetLocalLightTargetPDF を実行しない
しきい値は 2 つの CVar から導出される
推定重み = ライトの明るさ × 距離による減衰（BRDF・IES・影は見ない超概算）
r.MegaLights.MinSampleWeight ＝ 0.001 （推定重みがこれ未満なら足切り）
r.MegaLights.LightAttenuationFalloﬀ ＝ 0.18 （下げるほどしきい値が上がり、多くのライトが落ちる）
しきい値 = MinSampleWeight ÷ LightAttenuationFalloﬀ ≒ 0.0056
推定重み ＜ しきい値 → 後段の重い GetLocalLightTargetPDF を実行しない


# Page. 74

![Page Image](https://bcdn.docswell.com/page/LJ1YXKDLEG.jpg)

選ばれ方 ① 距離と明るさ
ピクセル P から見たとき、どのライトが選ばれやすいか
ライト①
近い + 明るい
→ 重み 大 → 高確率で選ばれる
ライト②
遠い (減衰で弱い)
→ 重み 小 → たまに選ばれる
ライト③
影響半径の外 / 暗すぎる
→ EstimateLocalLight で候補外
ピクセル P


# Page. 75

![Page Image](https://bcdn.docswell.com/page/GJWGNDYQ72.jpg)

GetLocalLightTargetPDF — 本番の重み計算
ここまで残っているライトだけ、本番と同じシェーディング式で 1 回評価する
＝ GBuﬀer のベースカラー・ラフネス・法線で拡散＋鏡面反射を計算
（マテリアルグラフ（テクスチャ等）はベースパスで評価済み。ここでは再評価しない）
→
影無しで輝度を求める
Light Function は常に掛ける。IES は輝度がしきい値を超えたときだけ掛ける（無駄打ち回避）
r.MegaLights.MinSampleWeight ＝ 0.001 （輝度がこれ以下なら重み 0）
重み = log2(輝度 + 1) → 極端に明るいライトがサンプルを独占しないよう圧縮
Weight が 0 のライトは AddLightSample に渡らない


# Page. 76

![Page Image](https://bcdn.docswell.com/page/4EZL3GX373.jpg)

選ばれ方 ② 面の向きと鏡面反射
EstimateLocalLight は法線を見ない
→ ライト③ が落ちるのは TargetPDF
ライト①
N・L 最大 → 拡散の重み 大
視点
法線 N
ライト③
面をかすめる → N・L ≒ 0 → 重みほぼ 0
ライト②
視線の反射方向
→ ラフネスが低いと鏡面反射で
重みが跳ね上がる


# Page. 77

![Page Image](https://bcdn.docswell.com/page/Y76WXY4Z7V.jpg)

選ばれ方 ③ 重みが 0 になるケース
スポットライトの円錐外
面の裏側 (N・L ≦ 0)
法線 N
ライトが面の裏 → 重み 0
円錐の中 → 重みあり
円錐の外 → 重み 0
ほかに重みが 0 / 除外になるケース
ライティングチャンネルが違う (Material と Light の AND が 0) → SampleLight の入口で return
Rect ライトの裏面 / IES で完全に減光 / ライトの CastShadow や Aﬀect 系フラグが oﬀ


# Page. 78

![Page Image](https://bcdn.docswell.com/page/G75MXGQ974.jpg)

AddLightSample — 重みと乱数で決まる
1 ピクセルにつき既定 4 個を選ぶ。どれを選ぶかは「重み」と「乱数」で決まる
① 重み（GetLocalLightTargetPDF）
ライトの明るさ。重いほど高い確率で選ばれる
② 乱数（枠ごとに 1 個、シードはフレーム番号）
毎フレーム違う組み合わせになる
③ 重みには補正がかかる
前フレームに見えなかったライトは下げる(Guide by History)
点いた直後のライトの補正(LightPowerDelta)
ディレクショナルライトには上限をかける
しきい値未満は重み 0（選ばれない）
r.MegaLights.NumSamplesPerPixel ＝ 4 1 ピクセルで選ぶ個数（Scalability の Low / Medium は 2）
r.MegaLights.Debug 1 カーソル位置のピクセルで、候補ライトと重み・採否を一覧表示（右の画像）


# Page. 79

![Page Image](https://bcdn.docswell.com/page/9J29XYP5ER.jpg)

フレームごとに違うライトを選ぶ
刺す位置がフレームごとにずれるので、同じピクセルでも毎回違うライトが当たる
Frame 0
Frame 1
Frame 2
Frame 3
L1
L3
L2
L5
L3 L4
L8 L12
L1
L6
L3
L7
L3
L9
Temporal Filter が最大 12 フレーム分を積算
→
L3
L9
1 ピクセルあたり実質 48 サンプル相当


# Page. 80

![Page Image](https://bcdn.docswell.com/page/DEY48G56JM.jpg)

前半の処理
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
↓
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 81

![Page Image](https://bcdn.docswell.com/page/VJNYQG4178.jpg)

MegaLightsの全体像
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 82

![Page Image](https://bcdn.docswell.com/page/YE9PDWQYJ3.jpg)

処理の流れ (2) — 影をトレース
それぞれのシャドウレイを、各手段で順に解決していく
① VSM
Nanite ジオメトリをラスタライズして影を作れる
シャドウマップ描画のコストがかかる
② Screen Trace Depthベースでスクリーントレース
③ World Trace
HWRTワールド空間をトレース。
BVH(TLAS/BLAS)生成が必要となり
フォールバックメッシュが重要
各段が返すのは「遮られたかどうか」
Ray Tracing or VSM
r.MegaLights.DefaultShadowMethod =
&quot;0&quot;
(デフォルト:Raytracing)


# Page. 83

![Page Image](https://bcdn.docswell.com/page/GE8D3NGKED.jpg)

未完了なものを順次トレース処理していく
完了したら以降はスキップ
CompactLightSampleTraces
未完了のレイだけ集める
VirtualShadowMapTraceLightSamples
VSM を持つライトのサンプルのみ
CompactLightSampleTraces
未完了のレイだけ集める
ScreenSpaceRayTraceLightSamples
スクリーンスペースでトレース
CompactLightSampleTraces
未完了のレイだけ集める
HardwareRayTraceLightSamples
ハードウェアレイトレーシング
各段の入口で Compaction が走り、まだ完了していないレイだけを集めて処理
影を落とさないライト（CastShadow オフ）は最初から完了扱いなので、1 回目の時点で外れる


# Page. 84

![Page Image](https://bcdn.docswell.com/page/LELMVPGP7R.jpg)

VSM Trace — Nanite の高品質な影
シャドウマップベース (VSM) で処理。レイは飛ばさない
シャドウ方式が VSM のライトが対象
Nanite メッシュの高品質な影がそのまま使える
ライトごとに Shadow Depth の描画が必要
ディレクショナルライトは既定で MegaLights の対象外
＝ 通常の VSM で描かれる
綺麗だが、ローカルライトでは更新コストが乗りやすい
VSM の詳しい挙動は過去資料をご参照ください
Unreal Engine 5 における レンダリング &amp; デバッグTips
r.MegaLights.DirectionalLights ＝ 0 ディレクショナルライトを MegaLights で扱うか（既定オフ）
r.MegaLights.VSM.MarkPages ＝ 1 必要なサンプルのページだけをマーク（オフだと保守的に全ページ）


# Page. 85

![Page Image](https://bcdn.docswell.com/page/4JMYG4Q2JW.jpg)

Screen Trace — 処理負荷軽く、差分も吸収する
深度バッファ(HZB)でレイトレース。当たれば遮蔽が確定して以降スキップ
冒頭で見たケースを拾える
Masked マテリアルの抜けを解決できる(離れていれば)
レイトレ用の Fallback Mesh と実メッシュの差を吸収できる
一方でエラーも出る（画面外は追えない、薄い物体の判定ミス）
それでも HWRT のコストを抑えるうえで非常に重要
MaxDistanceを調整することでScreenTraceで拾う数を調整可能
r.MegaLights.ScreenTraces ＝ 1
r.MegaLights.ScreenTraces.Quality ＝ 1（0 = 半解像度で高速）
r.MegaLights.ScreenTraces.MaxDistance ＝ 100 追う距離（ワールド空間）
r.MegaLights.ScreenTraces.MaxIterations ＝ 50 HZB の反復上限
r.MegaLights.DistantScreenTraces ＝ 2 レイトレシーンの外側を線形トレースで補う
r.MegaLights.Debug.TraceStats ＝ 1 各Trace段階のレイの数を表示


# Page. 86

![Page Image](https://bcdn.docswell.com/page/PJR9ZW8579.jpg)

不透明以外のMegaLights — 類似の別パス
ここまで言及していませんでしたがVolume系のパスがそれぞれ存在
Uniﬁedオ
ン
Volume ボリュメトリックフォグ
Translucency Volume 半透明用のライティングボリューム
Hair Strands ／ Front Layer Translucency
Light Grid は不透明と共通
ただしサンプリングはボリュームのセル単位
→ 選ばれるライトは不透明と一致しない
Volume と Translucency Volume は Uniﬁed で
共通のデータを使う（Volume.Uniﬁed 既定オン）
r.MegaLights.Volume ＝ 1 r.MegaLights.Volume.Uniﬁed ＝ 1 r.MegaLights.TranslucencyVolume ＝ 1
r.MegaLights.Debug 1 = Opaque／2 = Volume／3 = Translucency Volume
4 = Hair Strands／5 = Front Layer Translucency
Uniﬁedオ
フ


# Page. 87

![Page Image](https://bcdn.docswell.com/page/PEXQ9P8XJX.jpg)

World Trace — ハードウェアレイトレース
Ray Tracing Scene（BVH）にレイを飛ばす。ここまで残ったレイを処理
当たり判定は Fallback Mesh に依存する（Nanite の実形状ではない）
通常は Inline Ray Tracing。当たった時点で打ち切る
Masked を評価するモードもある
Inline で当たったサンプルだけ、AHS 付きで再トレース
r.MegaLights.HardwareRayTracing ＝ 1
r.MegaLights.HardwareRayTracing.Inline ＝ 1
r.MegaLights.HardwareRayTracing.EvaluateMaterialMode ＝ 0
0 = 評価しない（既定）／1 = 全レイが RayGen（フル）／2 = 必要に応じてAHS再トレース
r.MegaLights.HardwareRayTracing.MaxIterations ＝ 8192


# Page. 88

![Page Image](https://bcdn.docswell.com/page/3EK9PDK9ED.jpg)

Raytracing Scene — ここが本当のコスト源
MegaLights 自体のコストはある程度一定化できる
サンプル数が固定で間引かれる
膨らむ危険があるのは Raytracing Scene 側
Lumen と共通の TLAS / BLAS を使う
負荷を下げる → ジオメトリの重なりを減らす/ カリング
Dynamic BLASを減らすか軽量化
メモリを下げる → BLAS を軽くする
同じメッシュ・LOD なら BLAS は共有される
Fallback Mesh / Ray Tracing Proxy / LOD の見直し
Lumen と MegaLights はTLAS / BLASを共有する
r.RayTracing.Visualize
InstanceOverlap
→ 削減効果も共有される


# Page. 89

![Page Image](https://bcdn.docswell.com/page/L73WXRZ975.jpg)

BLAS を軽くする — LOD と Proxy
Skeletal Mesh
LOD メッシュを用意しておき
レイトレ用の Ray Tracing Min LOD を指定
Static Mesh
Ray Tracing Proxy を設定すると
LOD0 と LOD1 相当の軽量メッシュを生成
プロジェクト設定 &gt; Rendering &gt; Hardware Ray Tracing &gt; Generate Ray Tracing Proxies
要再起動。オフのとき Nanite は Fallback Mesh が使われる


# Page. 90

![Page Image](https://bcdn.docswell.com/page/87DK2YR8JG.jpg)

RaytracingのCulling と Residency
Culling「今回使うか」
Residency「メモリに置くか」
毎フレーム・ビューごとに判定
予算の中で選別（プール制）
r.RayTracing.Culling（既定 3）
r.RayTracing.Culling.Radius（既定 300m）
r.RayTracing.Culling.Angle（既定 1度）
r.RayTracing.ResidentGeometryMemoryPoolSizeInMB
(既定 400 MB)
r.RayTracing.NumAlwaysResidentLODs (既定 1)
対象：現在の TLAS のインスタンスリスト
対象： BLAS の実体データ
つまり「カリングされて画面に写らないオブジェクト」も、BLAS はメモリに残る
Culling は描画コストと TLAS ビルドコストの削減、Residency は常時メモリの削減
プールの予算を超える場合に、使われていないものからLODの粗いものに追い出し
stat RayTracingGeometry Requested と Resident などを確認して


# Page. 91

![Page Image](https://bcdn.docswell.com/page/VJPK16WWE8.jpg)

おすすめ資料
レイトレーシング関連の最適化は
公式ドキュメント「Ray Tracing Performance Guide」にまとめられている
Ray Tracing Performance Guide
https://dev.epicgames.com/documentation/unreal-engine/ray-tracing-performance-guide-in-unreal-engine


# Page. 92

![Page Image](https://bcdn.docswell.com/page/2EVVY389EQ.jpg)

処理の流れ (3) — シェーディングする
⑤ ShadeLightSamples
1/2 解像度のサンプルをフル解像度へアップサンプル（この中で行う）
選ばれたライトでライティング × シャドウレイの可視性
⑥ VisibleLightHash
見えたライトを次フレームの Guide by History へ


# Page. 93

![Page Image](https://bcdn.docswell.com/page/57GL9354EL.jpg)

ShadeLightSamples — アップサンプルも含む
選ばれた最大 4 個だけで、フル解像度でシェーディングし直す
ライティングの計算自体は通常のパスと同じ
1/2 解像度のサンプル位置は毎フレーム動く（2×2 を 4 フレームで一巡）
拡大時にどの近傍を引くかも毎フレーム変わり、Temporal で解像度が戻る
r.MegaLights.DownsampleMode ＝ 2
0 = 等倍 ／ 1 = チェッカーボード ／ 2 = 半解像度
0 にするとレイの本数がそのまま 4 倍になる。
中間が 1（チェッカーボード）
全解像度
(1x1)
■■■■
■■■■
■■■■
■■■■
チェッカーボード
(2x1)
1/2 解像度
■□■□
□■□■
■□■□
□■□■
■□■□
□□□□
■□■□
□□□□
(2x2)


# Page. 94

![Page Image](https://bcdn.docswell.com/page/4EQYW5ZRJP.jpg)

デノイズの前にやっている 3 つのこと
① Albedo をデノイズから外す（demodulate）
照明成分だけをデノイズし、終わってから Albedo を掛け戻す
② 確率によってライトの重みを補正。まれにしか選ばれないライトの重みを頭打ちにする
重みは 1/確率。1/1000 のライトが当たると 1000 倍明るくなる ＝ ファイアフライ
③ うまくサンプルできた画素(ShadingConﬁdence:信頼度)は、テンポラルフレーム数を減らす
ライトが 1 個なら 2 フレーム、多数が効く画素は最大 12 フレーム
r.MegaLights.MaxShadingWeight ＝ 20
r.MegaLights.MaxShadingWeightForHiddenLight ＝ 5
白いつぶつぶ（ファイアフライ）が出たら下げる。代償は点いた瞬間が暗くなること
r.MegaLights.ShadingConﬁdence ＝ 1
うまくサンプルできた画素はデノイズを弱める


# Page. 95

![Page Image](https://bcdn.docswell.com/page/KJ4WK93Q71.jpg)

処理の流れ (4) — 安定させる
⑦ Temporal
履歴を最大12フレーム蓄積
⑧ Spatial
信頼度 (Shading Conﬁdence) が
低いところほど強くフィルタ
ここで取り切れなかった誤差がノイズや残像になってしまう


# Page. 96

![Page Image](https://bcdn.docswell.com/page/LE1YXK1L7G.jpg)

デノイズの調整 — ノイズと残像のバランス
まず Temporal の蓄積フレーム数でノイズと残像のバランスを取る
r.MegaLights.Temporal.MaxFramesAccumulated ＝ 12
足りなければ、履歴をどこまで扱うか調整する
r.MegaLights.Temporal.NeighborhoodClampScale ＝ 1.0
緩めるとノイズ減・残像増
r.MegaLights.Temporal.HistoryDistanceThreshold ＝ 0.03
下げると壁際の残像減
Spatial は、まだ履歴が溜まっていない画素を周りの画素で埋める
カメラが動いて新しく見えた場所など、Temporal が使えない間だけ強くかかる
r.MegaLights.Spatial.KernelRadius ＝ 8
r.MegaLights.Spatial.NumSamples ＝ 4
信頼度は 1 画素に効くライトの候補が多いほど下がる
→ 候補が少ないほど安定する


# Page. 97

![Page Image](https://bcdn.docswell.com/page/GEWGND8QJ2.jpg)

MegaLightsの全体像
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 98

![Page Image](https://bcdn.docswell.com/page/47ZL3G83J3.jpg)

MegaLightsの全体像
MegaLightsパス以外の既存の処理
Light Grid → RayTracing Scene Update
① ライトを選ぶ
Tile Classiﬁcation → GenerateLightSamples
↓
② 影をトレース
VSM → Screen → World(Raytracing)
↓
③ シェーディングする
ShadeLightSamples (Resolve)→ VisibleLightHash
↓
④ 安定させる
Temporal → Spatial


# Page. 99

![Page Image](https://bcdn.docswell.com/page/YJ6WXYPZJV.jpg)

最適化の進め方
① Light Complexity で候補ライトが多い場所を特定
ライトの Attenuation Radius を絞るのが最も効く
② Shadow Caster Quality でプロキシの破綻を確認
Fallback Mesh / RT Proxy の整備は品質に直結
この 2つが重要。負荷にも画質にも効く


# Page. 100

![Page Image](https://bcdn.docswell.com/page/GJ5MXGK9J4.jpg)

MegaLights の スケーラビリティ
スケーラビリティの Shadow QualityにいくつかのMegaLights の設定が行われている
Low
Medium
High
Epic
Cine
r.MegaLights.NumSamplesPerPixel
2
2
4
4
4
r.MegaLights.DownsampleMode
2
2
2
2
0
r.MegaLights.ScreenTraces.Quality
0
0
1
1
1
r.MegaLights.FrontLayerTranslucency.Allow
0
0
1
1
1
r.MegaLights.Spatial.UseHistorySpatialVariance
0
0
1
1
1
r.MegaLights.Volume.GridPixelSize
16
16
16
8
8
プロジェクト設定やデバイスプロファイルで設定されていることも


# Page. 101

![Page Image](https://bcdn.docswell.com/page/LE3WXRZ2E5.jpg)

まとめ
本セッションでは、発生しうる問題を中心に紹介させていただきましたが
MegaLights は今まで難しかった多数のライトの表現が可能になる
非常に強力なツールだと思います。
本セッションの内容が、
みなさんのゲーム開発に役立てば幸いです


# Page. 102

![Page Image](https://bcdn.docswell.com/page/8EDK2YR67G.jpg)

Thank


