【UE4小ネタ】マテリアルのAOってなんだ

UE4のマテリアルに「Ambient Occlusion」っていう入力チャンネルあるじゃないですか。

マテリアルのAOチャンネル

ポストプロセスでもシェーダでもなくマテリアルチャンネルにAOあるってどういうこと? って思ってドキュメント見るじゃないですか。

Material入力 | Unreal Engineドキュメント

ドキュメントの説明

具体的な使い途がピンとこないというか、単にBase Color等のテクスチャにAOを乗算するのとなにが違うのか、この説明だとわからないですね。はて?

で、僕もしばらくこの疑問は放置してたのですが、先日どっかで「マテリアルのAOは間接照明をマスクするやつだ」っていうのを見かけまして、その後あらためて検索してみたらこちらの記事にも解説がありました。

Material Ambient Occlusionについて(株式会社けだまワークスさんのブログ)

なるほど! と思い、自分でも実際にいろいろ試してみたのが今回の小ネタ記事です。

先に結論から言うと、主として「キャラとかのMovableなアクターに対するVolumetric Lightmapの間接照明に自己遮蔽の影を補う」ためにあるもののようですね。

Volumetric Lightmapと「自己影」

UE4の間接照明は通常、事前計算されたライトマップを使います。背景にある動かない(Staticの)物体の場合、間接照明はサーフェスにテクスチャとして焼き付けてしまってかまわないのですが、キャラクターなどの動く(Movableの)物体の場合は、移動に伴って間接照明も変化するのでそうもいきませんね。そこで、ライトマップを空間=ボリュームに一定間隔で計算して、それを動く物体の間接照明で参照するというのがVolulmetric Lightmapです。

※StaticアクターでVolumetric Lightmapを使ったりMovableアクターでSurface Lightmapを使ったりすることもできますが、原則から外れたややトリッキーな設定になりますね。

こちらの画像が照明とVolumetric Lightmapのサンプルを表示させたものです。

Volumetric Lightmapによる間接照明

空中に等間隔で並んでいるピンポン球みたいなのがVolumetric Lightmapのサンプル点で、真ん中に立ってるキャラクターの間接照明は直近のサンプル点の持つ情報を参照しています。事前計算の情報しか使ってないのにこれだけ馴染む間接照明が得られるというのは、非常によくできた仕組みですね。

で、そのVolumetric Lightmapにも弱点はあり、間接照明を遮蔽する「自己影」の計算まではさすがにできないので、レイトレースのGIによる間接照明と比較すると「影が抜ける」感じになります。という話を前にあった「UE4 Ray Tracing Night」でお話ししました。そのとき作ったサンプル画像の一部を抜いてきたのがこれです。

ライトマップGIとレイトレGIの比較

特に耳のあたりで、間接照明の「自己影」のあるなしの差が出ていますね。動的なレイトレGIと比べると事前計算のライトマップGIはちょっと惜しい感じです。「Ray Tracing Night」のときはお恥ずかしながらマテリアルAOの使い方を知らなかったのでこれを「ライトマップの限界」と判断しておりました。

間接照明の自己影をAOテクスチャで代替する

マテリアルのAOは「3DツールでベイクしたAOテクスチャを入力するところ」ということはわかったので、実際にやってみます。

まずキャラクターのAOをテクスチャとしてベイクしました。このキャラクター自体は3D-Coatで作っているので3D-Coatから書き出したAOのテクスチャもあるのですが、そちらは全体に軟調なトーンで要調整な感じだったので、C4Dで設定を加減してベイクしました。

C4DでベイクしたAO

で、これをUE4のキャラクターのマテリアルのAOにつなげました。マテリアルAOありなしで比較するとこうなります。

マテリアルAOありなし比較

マテリアルのAOを使ったほうは間接照明に「自己影」の要素が反映されていて、レイトレのGIに近い感じになっていますね。Volumetric Lightmapによる間接照明を事前計算のAOテクスチャでマスクすることで「影抜け」を防ぎ、より説得力のあるライティングができるようになるわけです。

ちなみにこちらのほうが上のレイトレGIよりも間接照明の影が濃いですが、そこはAOテクスチャをベイクするときの設定次第です。テクスチャ自体は濃いめに(つまり明暗の差を最大限確保して)ベイクしておき、最終的な濃さはマテリアルインスタンスのパラメータで調整できるようにしとくといいかなと思ったのでこうなっています。

マテリアルAOの濃さの調整

マテリアルAOの効果の詳細

マテリアルのAOは「間接照明だけをマスクする」というところが重要なので、それがわかりやすいようなサンプルを作ってみました。

キャラクターのほか、こちらのソファも同様にベイクしたAOテクスチャをマテリアルのAOに設定し、Movableアクターとして配置してみます。

C4DでベイクしたソファのAOテクスチャ

このソファに、ポーズを取らせたキャラクターを座らせます。こちらも同じくMovableアクターです。ライティングビルドした四角い部屋に配置するとこうなります。ソファとキャラクターはMovableアクターなので、自由に動かすことができます。

シーンのセットアップ

逆光のライティングでマテリアルのAOの有無を比較すると、効果は歴然としています。マテリアルのAOがないと間接照明には顕著な「影抜け」があり、立体感の乏しい描写です。いっぽうマテリアルのAOがあるほうは、間接照明の中にも引っ込んでいるところに影ができていて、格段に描写が改善しています。

マテリアルのAOありなし比較(逆光)

順光のほうはというと、ほとんど差が見られません。マテリアルのAOは直接照明には影響しないので、直接照明が支配的な順光のライティングでは見えてこないようです。もしAOテクスチャをベースカラーに乗算した場合には、直接照明のライトが当たっていても暗くなってしまうので「いかにもAOをのっけた」感じに見えてしまいます。こちらのマテリアルのAOの場合は直接当たっているライトの明るさには影響しないため、そのような違和感がありません。とてもよくできていますね。

マテリアルのAOありなし比較(順光)

マテリアルのAOは事前にベイクされたテクスチャを使用するので、もちろん限界もあります。間接照明のみの表示にしてチェックしてみます。

間接照明のみの表示

まず、別々のMovableアクター同士が近接している部分ではAOテクスチャ自体に影がないので、マテリアルのAOを使っても「影」の描写は出ません。この例でいうと、キャラクターとソファが接しているところには「影抜け」が起きています。

また、キャラクターのようなスケルタルメッシュではAOテクスチャはベイクしたときのポーズを基準にしているので、ポーズが変わって変形した結果として近接している部分にも影の情報はありません。キャラクターの手が腹部に接触している部分は「影抜け」が起きています。

公式の情報らしきもの

ドキュメントには前述のようなあやふやな説明しかありませんでしたが、検索したらUE4 Answerhubに情報がありました。

Ambient occlusion node in material does nothing

「マテリアルのAmbient Occlusionノードってなにもしてないのでは」という問いに対し、STAFFマークのついてる人から「It is now multiplied with the lightmap, stationary sky light and reflection capture specular. /ライトマップ、ステーショナリースカイライト、リフレクションキャプチャのスペキュラに乗算されるようになったよ」と回答がありました。どうも以前はもっと多くの照明要素に対して効果があったものが、Gバッファとの兼ね合いで少し減ったようなことも書かれています。ただ、この記事自体も2014年のものなので、2019年現在ではまた状況が変わっているかもしれません。

で、マテリアルのAOの使いどころは

マテリアルのAOの使いどころなのですが、やはり上記のようなキャラクター等のMovableアクターでVolumetric Lightmapに「自己影」を補うことを想定しているのではないかと思います。と思って実際にマテリアルのAOが使われているキャラクターアセットとかないかなと探してみたら、あることはあるのですが定石というほどでもない? キャラクター以外でも、家具とかをMovableアクターとして配置する場合はマテリアルのAOを入れておくとよさそうな気がします。

間接照明に対するフィルタとして使えるなら、色をつければノンフォトリアリスティック表現にいんじゃね? と一瞬思ったのですが、実際にやってみると色味は反映されませんでした。「赤」でも「白」でも結果は同じだったので、RGBでなくHSVのVだけ見てるっぽいですね。

マテリアルAOに赤を入れた場合も、色味は反映されず

Staticのアクターではどう使うのだろう

ちなみにマテリアルのAOはStaticのアクター(間接照明のモードがSurfaceのアクター)でも効果があり、AOテクスチャはライトマップに乗算されるようです。Surfaceのライトマップはどっちにしろ遮蔽する影ごとベイクされるので、あえてAOテクスチャで補う必要あるんかな? と思いましたが、間接照明のディテール情報だけをマテリアルAOのテクスチャとして持っておくと考えれば意義があるかもしれないですね。たとえばライトマップ解像度に余裕がなく、ライトマップにはおおまかな明暗程度しか持つことができなくても、マテリアルのAOで立体感を補うことができそうです。同じAOテクスチャを使うアクターが多いほど、すべてのアクターについてユニークな情報を保持するライトマップよりも効率が良いということもあるかもしれません(ないかも)。