既に複雑なプロパティ セットをさらに複雑化することなく、システム全体を改善します。
なお、この変更では、プロジェクトの外観の視覚的な一貫性を維持するためのアップグレード パスは提供されますが、Unreal Engine の以前のバージョンの既存の自動露出システムとの下位互換性は提供されません。
このブログでは、既存のシステムの問題点と、このような変更を行った理由について説明します。また、この変更が今後の自動露出にどのように (プラスに) 影響するかについても説明します。
ヒストグラム アルゴリズムと基本アルゴリズム
これまでのヒストグラム アルゴリズムと基本露出アルゴリズムは、Epic Games レンダリング チームの意図に反してユーザーにとってわかりやすいものではないというだけではなく、必ずしも思い通りのビヘイビアを実行できませんでした。今回の変更の内容と Unreal Engine 4.25 でこの変更を行った理由を理解していただくため、これまでにヒストグラム アルゴリズムと基本露出アルゴリズムがどのように機能していたかについて確認しましょう。- 基本アルゴリズムでは、シーンの対数輝度平均を使用して、測光した露出を決定します。
- ヒストグラム アルゴリズムでは、シーン全体を使用するのではなく、ヒストグラムのターゲット範囲の上下のピクセルを破棄します。この方法では、破棄しなかったピクセルの対数輝度平均を使用して、ターゲットの露出を決定します。
これらのアルゴリズムでは、「ポスト プロセス ボリューム」の露出設定に基づいて異なる結果が生成されていました。これら 2 つのアルゴリズムが期待通りのわかりやすい方法でビヘイビアを適切に実行する仕組みを特定するため、次の 2 つのルールを作成しました。
- グレーはグレーである必要がある。つまり、均一なライティングで照らされている 18% グレーの標準反射板 (0.18 cd/m^2 のエミッシブ サーフェス) がある場合、その画面上のターゲットの色は 0.18 である必要があります。
- ヒストグラム全体が基本に一致する必要がある。つまり、ヒストグラムの低域と高域を 0〜100% に設定した場合は、基本露出アルゴリズムと同じ外観が得られる必要があります。
以上のルールを指針として、これらのアルゴリズムとそのプロパティが多くの混乱を発生させた理由と、Unreal Engine 4.25 でこの問題点がどのように改善されたかについての例を確認しましょう。
4.24 では、0.18 cd/m^2 で測定できる単一のサーフェスを含むシーンから開始して、ヒストグラム範囲を 1〜99% に設定すると、レベル ビューポートで次の結果が得られます。
(左) ヒストグラム モード (RGB 254)、UE 4.24、(右) 基本モード (RGB 111)、UE 4.24
ヒストグラム露出アルゴリズムはほぼホワイト (RGB 254 で測定) に収束され、基本露出アルゴリズムはグレー (RGB 111 で測定) に収束されます。これはガンマ 2.2 空間では 16% グレーです。
では、なぜこのような問題が発生し、4.25 ではこの問題がどのように改善されたのでしょうか?
ヒストグラム モードの当初の目的は、ユーザーがヒストグラムの中央を調整しないで済むようすることでした。正確には、デフォルト値は 80〜98% であるため、ヒストグラムの平均はホワイト ポイントになります。
基本モードでは、シーンの輝度平均の計算がグレー ポイントに使用されます。グレー ポイントはキャリブレーション定数によって定義され、キャリブレーション定数のデフォルトは 16% グレーです。
どちらのモードも単独では、この解釈は妥当です。ヒストグラムの露出をホワイト ポイント用に調整し、フル シーン モードをグレー ポイント用に調整することは理にかなっています。ただし、パラメータを共有する同じようなモードが、互いに前述のような異なるビヘイビアを生成することが混乱を招いています。
調査の結果、次の選択肢が得られました。
- 特に変更は行わず、このまま自動モードとヒストグラム モードに異なった動作をさせる。
- 両方を同じモードにする。ただし、下位互換性を確保するめフラグとパラメータを追加する。
- 両方のモードを統合する。ただし、下位互換性は提供しない。
Epic Games レンダリング チームは 3 番目の選択肢を選びました。
1 番目の選択肢には、混乱を招く、わかりづらいパラメータをアーティストが使用しなければならないという問題があります。2 番目の選択肢では、さらにわかりづらいパラメータが作成され、既存の問題が悪化します。これらのアプローチを 3 番目の選択肢に統合することで、アーティストが使用するツールの操作性を向上させると同時に、複雑さと混乱を軽減することができます。
Unreal Engine 4.25 では、ヒストグラム モードと基本露出モードの両方がグレー ポイントに収束します。つまり、ヒストグラム モードでは、ヒストグラムの平均をグレー ポイントとして解釈します。基本露出モードのキャリブレーション定数は削除しました。
4.25 で行った自動露出への変更の結果は、次のとおりです。
(左) ヒストグラム モード (RGB 116、(右) 基本モード (RGB 117)
RGB 値を測定するときは、ヒストグラム モードと基本モードの両方が同じ標準グレーに収束されます (丸め誤差による若干の差は無視)。次の式を使用すると、どちらのモードも 18% グレーという単一の値になります。
(0.18^(1.0/2.2))*255=116.95
注:ヒストグラムをホワイト ポイントに移動したい場合は、[Exposure Compensation (露出補正)] パラメータを変更することで、引き続き実行できます。
1.2 から 1.0 へのスケールの変更
露出値は Unreal Engine では EV100 と解釈されています。では、EV100 とは何でしょうか?EV100 は簡単に理解できるものではありませんが、こちらで詳細を確認できます。輝度値が cd/m^2 で指定されると、そのライト値の EV100 値は、通常、次の式で計算されます。
EV100 = log2(luminance/1.2)
多くのユーザーにとって、この式は混乱がますだけです。これは、大半のユーザーが、0.18 というエミッシブ値は0.18 (ガンマ補正を考慮) と画面に表示される「ユニットレス (単位を含まない)」環境での作業を好むからです。前のバージョンでこれを実行するには、log2(1/1.2) = -0.263 というわかりづらい露出補正値を使用する必要がありました。
この追加のバイアスでは、このバイアスで解決する混乱よりもはるかに大きな混乱を招くことになるため、今後、このバイアスはデフォルトでは削除されます。ただし、必要に応じて、再度追加することもできます。
1.2 という物理的基礎
これまでの Unreal バージョンの自動露出で使用した EV100 の式に 1.2 という値が含まれていたのはなぜでしょうか?
この数式は ISO 規格12232:2019 で定義されています。当社はこの規格をカメラの物理的基礎として使用しています。実世界では、レンズは完全ではなく、レンズに入射するすべての光が実際にセンサーに当たるわけではありません。ほとんどのアプリケーションで、レンズの透過率は 0.65 と想定されています。つまり、レンズに入射する光の 65% がセンサーに当たり、その他の 35% は吸収、相互反射、および口径食により失われるということです。
この ISO 規格に基づき、ISO 100 のサチュレーション ベースのスピードで、レンズは 0.78/q (ここで、q はレンズの透過率) の値でサチュレーションします。ほとんどのアプリケーションでは q=0.65 を採用しています。そのため、次の結果が得られます。
0.78/0.65 = 1.2.
ただし、Unreal Engine の仮想レンズは実際にはこのとおりに動作しません。仮想レンズは相互反射や吸収によって光が失われることがないからです。そのため、レンダリング チームでは q を r.EyeAdaptation.LensAttenutation で制御できるユーザー定義変数にしました。
注:デフォルトでは、Unreal Engine のレンズの減衰を「0.78」に設定することで、UE4 のライティングはユニットレスになります。これまでの 1.2 というスケールを維持する必要がある場合は、レンズ減衰の変数を以前の暗黙的な値「0.65」に設定することができます。
物理カメラ パラメータの改善
物理ベースのカメラのパラメータでは、別の問題が生じていました。[Manual (手動)] 測光モード (ポスト プロセス ボリュームおよびカメラ設定で使用可能) を使用する際に、手動カメラが実際の物理カメラと同じように動作するように、[Exposure (露出)]/[ISO]/[Aperture (絞り)]/FrameRate (フレームレート)] が考慮されていました。このアプローチには、ワークフローに問題が生じるという欠点がありました。一般的なユース ケースでは、シーンが自動露出を使用して設定されると、合理的な外観が作成されます。ヒストグラム モード (左下) では問題ないように見えますが、手動モード (右下) に切り替えると、露出が過度に暗くなります。
(左) ヒストグラム露出がほぼ 0、(右) 手動露出がほぼ 10
手動測光モードを使用すると、自動露出でカメラのパラメータが考慮されるため、シーンが暗くなります。このモードの本来の目的は、物理カメラを再現する正確な絞り値と被写界深度 (DOF) 値を使用して、実際のライティングをより簡単に調整できるようにすることでした。ただし、このモードには、自動カメラと同じシーンで手動カメラを使用するのは実際には不可能であるという欠点がありました。
このワークフローを改善し、よりわかりやすくするために、ポスト プロセス ボリュームに新しいフラグ [Apply Physical Camera Exposure (物理カメラの露出を適用)] を追加しました。このフラグでは、物理カメラ パラメータが自動露出に影響するかどうかを制御できます。つまり、露出補正が「0.0」に設定されている手動カメラは、このプロパティがオフになっている場合、「0」に設定されている自動露出シーンと厳密に一致します。
新しい露出測光マスク
アーティストが自分の環境で自動露出をより細かく制御できるように、独自の露出測光マスクを追加するマテリアル スロットを追加しました。このスロットを使用すると、アーティストは画面全体を対象とする独自のテクスチャを作成して、各ピクセルの影響をテクスチャ マスクごとの重要度で重み付けする箇所を制御できます。(Left) ポスト プロセス設定の [Exposure Metering Mask (露出測光マスク)] マテリアル スロット。(右) 露出測光マスク テクスチャの例
この測光マスクの例を使用すると、エッジに沿ってではなく、画面の中心に向かってピクセルにより多くの影響を与えることができます。これは、自動露出の安定化に役立ちます。たとえば、画面のエッジに明るいオブジェクトが表示されると、予測した自動露出値が突然変わる可能性があります。このタイプのマスクを使用することで、エッジに向かってサンプルの影響を低減し、より安定したジッターの少ない自動露出結果を得ることができます。
(左) 全画面露出を使用、(右) 露出測光マスクを使用。
注:中央の値により大きな影響を与えるように重み付けを適用したり、画面全体に均一に重み付けを適用したりできるコンソール コマンド r.EyeAdaptation.Focus は削除しました。このパラメータはこの新しい露出測光マスクと同じように機能しますが、ヒストグラム モードではなく、自動露出基本測光モードのみに影響を与えます。新しい露出測光マスクを使用すると、アーティストは、基本モードでもヒストグラム モードでも一貫して機能する、より細かい制御を利用できます。
HDR ビジュアリゼーション モードの改善
自動露出ワークフローを向上し続けることは、デバッグ モードおよびビジュアリゼーション モードも改善できることを意味します。注:このビューは、[Show (表示)] > [Visualize (視覚化)] > [HDR (Eye Adaptation) (HDR (明暗順応))] に移動して、レベル ビューポートから、または、ShowFlag.VisualizeHDR 1 コマンドを使用してコンソールから有効にできます。 この新しいインターフェースには次の 3 つの線があります。
- 青線は、ビューのターゲット EV100 露出値です。
- この線は、ヒストグラム モードと基本露出測光モードのどちらを使用しているかに基づいて、ヒストグラム内でのシーンの露出平均を示します。
- 紫線は、現在のシーン ビューの実際の EV100 露出値です。
- この線は、このビューに存在する現在の露出を示しており、常に青線に向かって移動しています。
- 白線は、露出補正調整後の最終的な EV100 露出値です。
- これは、ポスト プロセス パラメータで露出補正が調整された後のディスプレイの実際の露出値です。白線と紫線は、露出補正で設定された値に基づいた間隔でその差を維持します。この例では、白線と紫線がヒストグラムで 2.0 の差を維持しています。
注:HDR (明暗順応) ビジュアリゼーション モードがあらかじめオンになっている必要があります。次に、コンソール変数 r.EyeAdaptation.VisualizeDebugType を使用して、デバッグ モードを切り替えます。「0」(デフォルト) はトーン マッピング後のシーン カラーを指定し、「1」はヒストグラム デバッグ モードを指定します。
このモードのヒストグラム デバッグのビジュアリゼーションでは、非常に明るいピクセル (太陽など) や非常に暗いピクセル (暗い影など) が、実行される HDR 計算に含まれることはありません。このシーンでは、ターゲット ヒストグラムの範囲より下のものは赤で表示され、この範囲より上のものは青で表示されます。これにより、設定した高パーセンタイル範囲と低パーセンタイル範囲によって、不要なピクセルが計算から除外されます。 ピクチャーインピクチャー HDR シーン表現は削除しました。これは、上記のヒストグラム デバッグ ビジュアリゼーションに変更されました。
露出補正カーブ
また、このリリースでは、X 軸と Y 軸の値を取得する場所をより明確にするため、露出補正カーブを更新しました。このことを考慮すると、アーティストが、明るい領域と暗い領域では異なる露出補正を必要とすることは理解できます。アーティストは、ポスト プロセス ボリューム内でカーブ アセットを割り当てることで、希望の外観を実現できるだけでなく、環境内の露出補正に影響を与える値をより細かく制御することができます。
(左) ポスト プロセス カーブ アセットの割り当て、(右) カーブ アセット
注:コンテンツ ブラウザを使用してカーブ アセットをプロジェクトに追加するには、[Add New (新規追加)] ボタンをクリックして、[Miscellaneous (その他)] カテゴリに移動し、[Curve (カーブ)] を選択します。次に、CurveFloat を選択します。
HDR ビジュアリゼーション モードでは、X 軸 と Y 軸を表すカーブにある情報がすべて表示されます。ヒストグラム (1) の[Average Scene EV100 (シーン平均 EV100)] の値 (1) と青線 (実際の露出) 値は、カーブ アセットの X 軸を表しています。[Exposure Compensation (Curve) (露出補正 (カーブ))] はカーブの Y 軸を表します。この値に、[Exposure Compensation (Settings) (露出補正 (設定))] の値が加算され、[Exposure Compensation (All) (露出補正 (すべて)) の合計値が算出されます。 このシーンの [Average EV100 (平均 EV100)] は 0.548 です。この値は、カーブ アセットの X 軸に挿入され、0.864 という Y 値が返されます。その後、この 0.864 という値が、[Exposure Compensation (Curve) (露出補正 (カーブ))] として適用されます。 関連する値は、次のとおりです。
- [Average Scene EV100 (シーン平均 EV100)] は計算されたターゲット EV100 値であり、ヒストグラムの青線でも表されます。
- [Exposure Compensation (Settings) (露出補正 (設定))] は、ポスト プロセス ボリュームで設定された露出補正です。
- [Exposure Compensation (Curve) (露出補正 (カーブ))] は、カーブ アセットから得られる Y 値です。
- [Exposure Compensation (All) (露出補正 (すべて))] は、前の 2 つの値の合計であり、最終的な露出補正になります。
露出補正を「設定」と「カーブ」の値に分けることで、設定をより正確に制御できるだけでなく、露出補正が特定の方法で動作する理由をより明確に理解できます。
露出変更スピード
現在の値からターゲット露出値に露出を調整する方法に関していくつか全面的な変更を行いました。ヒストグラム ビューでこの変更を確認するには、時間に沿って青線 (ターゲット露出値) の位置に合わせて調整されている紫線 (現在の露出値) を辿ります。
対数領域の調整
最初の重要な変更は、すべての露出の移動が、線形値ではなく F 値を基準に実行されるようになったことです。この場合、露出の順応が対数刻みで適用されるため、F 値が同じ速度で上下に移動するように感じます。これは、これまでの設定 (下のグラフに示す) では実行できませんでした。たとえば、これまでの設定を使用して、現在の線形平均が 1.0 で、ターゲットの 1,000 まで移動すると、2 秒後に中間点の 500.5 に到達します。
同様に、同じ速度で反対方向に進むと、1,000 から開始して 1.0 まで移動し、2 秒で中間点に到達します。
直感的にはこのビヘイビアは理にかなっているように思えますが、知覚の観点から考えると問題になります。直線的には、どちらの方向でも同じカーブをたどっていますが、私たちは F 値などの対数空間の強度も感知します。たとえば、1.0 から 500.5 に移動すると約8 F 値になりますが、500.5 から 1000.0 に移動すると 1 F 値になります。
この場合、上に移動すると、最初の 2 秒間に約 8 F 値移動し、残りのカーブで 1 F 値移動します。ただし、下に移動する場合は、最初の 2 秒間で 1 F 値だけ移動し、残りの時間で 8 F 値移動します。このビヘイビアにより、ターゲット輝度まで上に移動するときは露出がきわめて迅速に移動し、ターゲット輝度まで下に移動するときは非常にゆっくり移動していると感じます。Unreal Engine 4.25 では、露出の調整が、時間の経過に伴い線形に実施されているように感じるよう変更されました。
新しい線形移動および指数移動
Unreal Engine 4.24 以前のバージョンでは、すべての露出調整は指数関数的に行われていました。このビヘイビアにより、次の 2 つ目の問題が発生していました。- 自動露出が輝度の細かい変動にすばやく順応していたため、ジッター ビヘイビアの発生につながっていました。
- 輝度の大きな遷移は、遷移の速度を低下させる実用的な手段がなく、常に高速で実行されていました。暗い領域から明るい領域にゆっくりと遷移することはできませんでした。
このような問題に対処するため、新しいアルゴリズムでは、ターゲット露出値から大きく離れているとき場合は線形曲線 (2) で始まり、ターゲット値に近づくと指数曲線 (1) に切り替わります。
前の例 (対数空間調整セクション) を使用すると、比較的明るいシーンに順応する際の最初の動作は線形で実行されます。ポスト プロセスの[Speed Up (スピード アップ)] および [Speed Down (スピード ダウン)] パラメータが F 値/秒単位で測定されるようになりました。
ターゲットの露出に近づくと、一次微分の連続性を維持する指数曲線を使用して、動作が線形から指数に切り替わります。この値は、コンソール変数 r.EyeAdaptation.ExponentialTransitionDistance を使用して制御することができます。この変数は、ターゲットから F 値離れた r.EyeAdaptation.ExponentialTransitionDistance での線形から指数への遷移を設定します。
デフォルトの指数遷移距離は 1.5 F 値です。スピード アップとスピード ダウンは、指数関数に基づく動作に切り替わる前に、1.5 F 値離れるまで露出を線形に調整します。
この動作の変更により、これまでのビヘイビアと比較して、次のような重要なメリットがもたらされます。
- コントロールでの、ジッターが軽減される。ターゲットの露出から大きく離れているときの順応は線形で実行されるため、画面に明るいスポットが表示されても、突発的に移動することはありません。
- これらのパラメータを使用すると、低速の順応が必要な場合により正確に制御を行うことができる。
モバイル パリティ
Epic Games China モバイル チームの取り組みにより、Unreal Engine 4.25 でサポートされているすべてのモバイル プラットフォームで自動露出をサポートし、最適化することができました。つまり、モバイルで、デスクトップおよびコンソール プラットフォームと同等の機能を備え、ヒストグラム、基本、手動の 3 つの自動露出モードがすべてサポートされるようになりました。注:モバイルでの自動露出パリティには、ES 3.1 のサポートが必要です。Unreal Engine 4.25 では、ES2 のサポートがエンジンから削除されました。
自動露出の新たなデフォルト
アルゴリズムの新たな変更により、ヒストグラム露出モードのデフォルト値が変更されました。これまでは、ヒストグラム露出モードのデフォルト値では、80% の低パーセンタイルと 98.3% の高パーセンタイル範囲を使用していました。これは、ほとんどのヒストグラムを無視し、ハイライトのみにフォーカスするように設計されていました。新しいデフォルト値は、10% の低パーセンタイルから 90% の高パーセンタイルまでの範囲を使用し、一貫性を実現するため基本露出モードに似た結果を適用します。これらの変更を行った後に、デフォルトの露出補正値 0.0 では、一般的なシーンに対して暗過ぎるということが判明しました。そのため、新しいポスト プロセス ボリュームのデフォルトの露出補正値を 1.0 に変更しました。ただし、[Auto Exposure Bias (自動露出バイアス)] プロジェクト設定にこのデフォルトを変更できるオプションがあります。
Unreal Engine 4.24 以前のバージョンのビヘイビアを再現したい場合は、ヒストグラムの範囲を 80% および 98.3% に変更できます。次に、log2 (1.0 / 0.18) = 2.47 の露出補正を適用します。
どちらのバージョンも合理的であり、どちらかのバージョンがユーザーのプロジェクトでより適切に機能します。ただし、新しい露出のデフォルトの方がより幅広いヒストグラムを提供するので、デフォルトでの異なる露出モード間の整合性が向上します。
既存のプロジェクトとコンテンツの自動更新
最後に、今回の変更では、解決しなければならないやっかいな問題が 1 つ残っています。Unreal Engine 4.25 にアップグレードするときに既存のコンテンツはどのように処理をするのか?ということです。理想的なのは、エンジンのどのバージョンでもコンテンツが同一の外観を保つことですが、このケースでは、その選択肢は実用的ではありませんでした。Epic Games レンダリング チームが選択したのは、プロジェクトを 4.25 にアップグレードするときに、露出補正に自動更新を適用するというアプローチでした。
更新のロジックは、「Engine\Source\Runtime\Private」フォルダの Scene.cpp の CalculateEyeAdaptationExposureVersionUpdate() に保存されます。
ここで考慮すべき主な変更点は、プロジェクトでヒストグラム露出が有効になっており、プロジェクト設定でデフォルトの輝度範囲が有効になっている場合、変更されたビヘイビアに合わせて細かい露出補正を適用することです。たとえば、最小ヒストグラムと最大ヒストグラムの平均が 89.15 の場合、1.5 という露出補正が適用されます。ただし、比較的幅広いヒストグラムを使用している場合、より小さい露出補正が適用されます。最小および最大平均が 50 の場合、1.0 の露出補正が適用されます。レンダリング チームでは、これまでの設定との完全な一致の保証を追求していました。しかしながら、これを実現するための変換は、シーンのコンテンツに依存するため、実現できませんでした。チームは、前述のデフォルトであれば既存のコンテンツに妥当な値を提供できることを突き止めました。
注:万一プロジェクトで変換に問題が発生しても、元の露出補正値は非表示の値 AutoExposureBiasBackup に保存されています。
まとめ
以上の変更により、下位互換性は提供されなくなり、既存のプロジェクトの外観が変更される可能性がありますが、レンダリング チームが希望し、目指しているのは、今後アーティストやデベロッパーの皆様が自動露出をこれまでよりはるかに簡単に操作できるようになることです。Epic Games レンダリング チームはツールの改善と更新に継続的な取り組んでいます。この取り組みでは、普段であれば満足するレベル以上の影響を及ぼす広範にわたる変更を行うこともあります。ここで説明した変更により、これまでよりも使いやすいインターフェースと操作性をユーザーの皆様に提供できることを希望しています。「自動露出」ドキュメントもこのブログで述べたトピックや変更について含むように更新予定です。