はじめに
Unreal Engineで物理的に正しいライティング(PBR)を行うため、現実世界のLux(ルクス)やEV100の値を設定する解説記事は増えてきました。
しかし、いざ物理的に正しくすると、「日中に炎エフェクトが見えなくなる」といったゲームデザイン上の問題に直面します。
この記事では、洞窟から出た時のような自動露出(Eye Adaptation)効果を生かしつつ、物理ベースのリアルな昼夜サイクルと、それに明るさが左右されない「記号的な意味を持つエフェクト」を両立させる方法を解説します。
ステップ1: EV値の計算とAuto Exposureの基本設定
まず、カメラ(PostProcessVolume)と環境光(SkyLight)を、昼夜サイクルに対応できる状態にします。
1. EV100の計算式
物理ベースのライティングを行うには、まず現実の「照度(Lux)」から、カメラが目標とすべき「適正露出(EV100)」を計算する必要があります。
18%ミドルグレーの物体に当たる照度(Lux)から、それを適正露出で撮影するための EV100 を求める式は以下になります。
$$
EV_{100} = \log_2 \left( \frac{Lux}{\pi} \right)
$$
2. 昼夜のEV値を計算する
この式を使って、昼と夜のEV値の「限界値」を計算してみましょう。
-
昼(PM 12:00):
- 快晴の太陽光を 100,000 Lux と仮定します。
- $EV_{100} = \log_2 (100,000 / 3.14159) \approx$ 15
- (雪原の反射なども考慮し、マージンを見て 18 を設定します)
-
夜(AM 0:00):
- 満月の月明かり(0.1 Lux)や星明かり(0.001 Lux)を考慮します。
- $EV_{100} = \log_2 (0.001 / 3.14159) \approx$ -8.3
- (よって、夜の限界値として -8 を設定します)
3. Auto Exposureの範囲を「物理的な限界」で固定する
ステップ1.2で計算した値を基に、PostProcessVolume の設定でカメラ(目)が適応できる限界の範囲を定義します。この設定は、ゲーム中一切変更しません。
-
Metering Mode:Auto Exposure Histogram(自動のまま) -
Min EV100: -8.0(星明かりを捉えられる限界値) -
Max EV100: 18.0(マージンを含んだ太陽光の限界値)
この設定を固定することで、カメラは「どんなに暗い場所(洞窟の奥)」から「どんなに明るい場所(雪原の直射日光)」まで、常に自動で露出を調整(Eye Adaptation)しようと動作し続けます。
(TIPS: UE 5.3ごろまでは Project Settings で Extend default Luminance range を有効にする必要がありましたが、最近のバージョンではデフォルトでこの広いEV100レンジが基準になっています)
ステップ2: DirectionalLightの「Lux」と「色」で昼夜を制御する
DirectionalLight(太陽/月)を制御するために、Curve アセットを2つ用意します。
-
C_DayNight_SunLux(Intensity用) -
C_DayNight_LightColor(Light Color用)
これらのカーブを使い、Tickイベントなどで DirectionalLight の値を更新します。
(デバッグ用に、DeltaTime * 0.1 などを加算して24秒で1日がループするような仕組みを作ると調整が楽です)
1. 「Lux」カーブ (物理的な光量)
- 昼 (12時): 100,000 Lux (快晴の太陽)
- 夜 (0時): 0.1 Lux (月明かり)
2. 「Color」カーブ (ゲーム的な色味)
-
昼 (12時):
(R:1.0, G:1.0, B:1.0)(真っ白) -
夜 (0時):
(R:0.1, G:0.1, B:0.15)(色あせた濃いグレー、少し青寄り)
なぜ「色」まで変えるのか?
Min EV100 が -8.0 のように低い値に設定されているため、カメラは夜(0.1 Lux)の暗いシーンを**「露出不足だ」と判断し、感度(EV値)を自動で -8.0 まで上げて(明るく補正して)しまいます。**
その結果、意図した「暗い夜景」にならず、ノイジーで明るい、まるで昼間のような画面になってしまいます。
本来は PostProcessVolume の Exposure Compensation (露出補正) の値を制御し、暗くしたいシーンや夜にマイナス値(例: -5.0)にするのが正確なアプローチかもしれませんがそのカーブの調整は少々面倒です。
そこで今回は簡単なサンプルとして、Light Color を夜間だけあえて「濃いグレー」にするという、より直接的な方法で「夜感」を演出します。
Auto Exposureはシーンを明るくしようとしますが、当たる光そのものが「暗いグレー」であるため、結果として彩度の低い、意図した「夜の雰囲気」の絵になります。
ステップ3: 「記号的な意味も持つエフェクト」を露出から守る
さて、ここからが本題です。
この物理ベースの露出制御が完成した世界で、プレイヤーが放つ炎の魔法エフェクト(マテリアルのエミッシブ輝度: 3000 cd/m²)を表示してみます。
-
正午:
EV100が18.0付近(暗く撮る設定)なので、100,000 Luxの太陽光に比べれば3000の輝度はとても小さい値なので深夜に光り輝いていた。エフェクトはほとんど見えなくなってしまいます。

これは物理的には正しいのですが、「当たり判定がわかりずらい!」などなど、非難轟々の嵐がやってきます。
ゲーム内の「記号的」な意味も持つエフェクトに「これが物理的に正しいんだ!」という言い訳は通用しません。
【解決策】 露出補正をマテリアルでキャンセルする
深夜用とお昼用のエフェクトを用意するのは無駄なので、1つのマテリアルで対処します。
幸い、UEには現在のカメラ露出補正値を取得するノードが用意されています。
- エフェクトが使用しているマテリアルを開きます。
-
EyeAdaptationInverse(目の順応の逆数) ノードを呼び出します。- このノードは、カメラがシーンを暗くしようとしている時(昼間)は大きな値を返し、明るくしようとしている時(夜間)は小さな値を返します。
- 元の
Emissive Colorの計算結果に、このEyeAdaptationInverseをMultiply(乗算) します。
- (補足) もし
EyeAdaptationInverseノードが見つからない古いバージョンを使っている場合は、Exposure (Eye Adaptation)ノードを呼び出し、元のEmissive ColorをこのノードでDivide(除算) しても全く同じ結果が得られます。
結果
このマテリアルを適用すると、エフェクトはシーンの露出設定(昼か夜か、洞窟の中か外か)に関わらず、**常にデザイナーが意図した通りの「見た目の明るさ」**で表示されるようになります。
---まとめ
- EV100の計算式 $EV_{100} = \log_2 (Lux / \pi)$ を基に、昼夜の露出限界(例: -8 と 18)を計算する。
-
EV Min/Max (範囲): 計算した限界値で全範囲で固定する。
- → 洞窟などの「明暗順応(Auto Exposure)」が常に機能する。
-
SkyLight (環境光):
Real Time Captureを有効化する。- →
DirectionalLightの変化に自動で追従させる。
- →
-
DirectionalLight (光量と色):
Curveアセットで動的に変更する。- →
Luxで物理的な光量を、Color(濃いグレー)でゲーム的な「夜感」を制御する。
- →
-
記号的VFX: マテリアルで
Emissive ColorにEyeAdaptationInverseを乗算する。- → 露出補正をキャンセルし、常に一定の見た目の明るさを保つ。
この手法で、物理的な正しさとゲーム的な「記号」としての見やすさを両立させることができます。





