ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

UE5 エミッシブの値を露出に関わらず一定に保つ

@goolee07 さんに続いて「UE Advent Calendar 2023」14日目の記事になります!

今年はエフェクト向けのマテリアル制作において鉄板の要素となる、シーンの露出に関わらず一定のエミッシブ値にする方法についてまとめておきたいと思います。

前置き


シーンの露出が変わるとシーン内のオブジェクトの色の値も当然変わりますが、必殺技や魔法やワープゲートみたいなエフェクトのエミッシブ値が、場所によって激しく発光したり暗くなってしまうのはゲームとして問題だったりします。

本来は露出の影響を受けるのが物理的に正しいと言えるとは思うのですが、スマホの画面が暗い場所なら自動で明るさを抑えるようになっているように、ゲームプレイ時のエフェクトも「機能性」の観点から「一定の見え方にする」というのが大事だったりもします。(もちろん、背景に設置するようなエフェクトをシーンに馴染ませる場合は話は別になると思います)

●露出による見え方の違い

実際どんな風に見えるのか? Content Examples のレベルに少し高いエミッシブ値を与えた箱を置いて、PostProcessVolume の Exposure Compensation の値を変えたスクショを3つ並べてみます。

▼ Exposure Compensation = 0.0

▼ Exposure Compensation = -5.0(発光感は失われます)

▼ Exposure Compensation = 5.0(激しく発光します)

では、どう解決すると良いのでしょうか?

具体的な解決方法


実は CEDEC 2015 のセッション「GameVFX Bootcamp 2015」内の講演の1つ「DX11世代におけるエフェクトの諸問題に関する実際の対応例」で、株式会社バンダイナムコスタジオの土屋さんが具体的な解決方法について触れられています。

CEDiLGameVFX Bootcamp 2015)でダウンロードできるスライド資料「104_2.pptx」にマテリアル内でエミッシブの値に補正を入れることで対処する方法が紹介されています。これは EyeAdaptation の値でエミッシブの値を割っていますが、"シーンの明るさが 2 倍になったらエミッシブ値を 1/2 にする" といった対処になっている認識です。
< 104_2.pptx の P.14 から引用>

当時同じ方法で対処していたので、これで良かったのだと安堵したのを覚えています。私の知る限り具体的な対処法の解説を目にしたのはこちらが初めてでした。

UE5 になった今でもこの方法が有効ですが、UE5 には「EyeAdaptationInverse」という専用のノードが追加されていて City Sample か何かのサンプルでエフェクト向けマテリアルに使われていたため、Epic さん的にも鉄板の対処方法なのかなと思っています。

ただ、UE でエフェクトを作る上でかなり大事な知識になると思うのですが、解説されているブログ記事等を見かけることがほぼ無いため、記事にしておこうと思いました。

結果


対策を入れた場合、露出が変わっても箱の色が一定に保たれているのが分かります!

▼ Exposure Compensation = 0.0

▼ Exposure Compensation = -5.0

▼ Exposure Compensation = 5.0

ちなみに周囲の背景の明るさが露出対策が無い場合のスクショと随分違うのは、箱のエミッシブによる Lumen GI への影響が大きく変わったためかと思います。

おまけ話 ①


マテリアルで取得できる Eye Adaptation の値と Emissive Color の値を Debug ノードで表示させてみました。動画内で3つ並んだ板は以下の違いがあります。

  • 左:露出対策なし
  • 中:Emissive 値を EyeAdaptation ノードで割ったもの
  • 右:EyeAdaptationInverse ノードを挟んだもの

EyeAdaptation ノードで割った結果と EyeAdaptationInverse を使った場合で値に全く違いが無いことが分かります。

モデルの下半分に表示しているエミッシブ値は、こちらの構成で表示しています。

UV 座標のグラデーションをマスクに利用するのは定番と思いますが、その際には Step 関数を利用すると境界を調整しやすくて便利です。

また、シーン中で Text Render Actor を利用していますが、デフォルトで指定されているマテリアルを複製して改造したものを利用しています。

中身は EyeAdaptationInverse で露出対策を入れつつ、シーンが明るい場合はテキストカラーを黒・暗い場合は白で表示するよう EyeAdaptation と SmoothStep も入れています。

なかなか悪くないと思いますがどうでしょう?

Actor から色を与えたい場合は、元々のマテリアルのように Vertex Color を使いつつ、シーンの明るさに応じて色を反転させてあげたりすることもできそうです。

おまけ話 ②


EyeAdaptationInverse の AlphaInput に値を入れるとどうなるかを軽く試してみましたが、入力する値によって出力される値が変わることと、LightValueInput によっても値が変わることくらいしか分かっていません。

こちらは結局どう使うと良いのかどなたかお分かりの方、教えてください!(Input 名から考えれば、半透明の場合に Opacity に繋ぐ値を入れておけってことでしょうか)

 

という訳で本記事はこれで終了です。いかがだったでしょうか?

非常に地味な内容ではありますが、エフェクトアーティストは知っておいた方が良いもののあまり取り上げられることが無い内容かと思ったので取り上げました。

そして明日は @nari-nari さんの記事になります!