Let's Enjoy Unreal Engine

Unreal Engineを使って遊んでみましょう

UE5 フォリッジでNaniteのOpaqueメッシュとMaskedメッシュの負荷を比較してみる

UE5.1が正式リリースされました。
docs.unrealengine.com

かなり新機能が多くて、把握するだけでも一苦労します。Lumen & Naniteも大幅にアップデートされており、検証したい項目が沢山ある状態です。その中でも特に気になっている部分でMaskedマテリアルをNaniteがサポートしてくれました!

Maskedマテリアルはフォリッジで配置する草木や樹木ではほぼ使われており、昔からゲームでは草木や樹木はMaskedのマテリアルで作られたものが非常に多かったので、これをサポートしてくれるということは非常に大きな意味があります。ただ実際にNaniteでMaskedメッシュを配置した場合どこまで効果があるのかがわかりませんので、実際に検証してみました。

今回の環境はUE5.1.0でRTX 3070を使って検証しています。それでは早速検証していきましょう。

検証環境

今回の検証では主に以下の2つのアセットを使っています。

Megascans: 草:プロップ・小物 - UE マーケットプレイス

Light Foliage:プロップ・小物 - UE マーケットプレイス

前者はMegascansで作られた非常にハイポリな草のメッシュ群で、後者は名前通り非常に軽いローポリな草のメッシュ群でMaskedマテリアルとなっております。前者はベースマテリアルがMaskedとなっていたため、今回用にベースのブレンドモードはOpaqueに修正しております。

比較はそれぞれ新規レベルでBasicを選択して作成し、何も設定変えずにほぼ空の状態からスタートしています。何も設定しないランドスケープを配置しフォリッジで同じ位置かつ同じ密度で配置したものを同じ角度からみたものを検証として利用します。

ちなみに今回の検証ではEarly Z-Passの"Mask Material only in Early Z-pass"オプションは有効化した状態で検証しています。Early Z-Passがよくわからない方は以下のスライドをどうぞ。

Mask Material only in Early Z-passの効果と仕組み | ドクセル

Opaqueメッシュを俯瞰した状態

Maskedメッシュを俯瞰した状態

ポリゴン数だけで言えば前者の方が圧倒的に高い状態です。当然Naniteメッシュにしていない状態の場合、前者の方が相当負荷が高く、そのままゲームで使うにはかなり厳しいということが予想できます。それでは順番に検証していきます。

負荷検証

まずはOpaqueメッシュをNanite化しないままで計測した状態です。 GPU 35.40 ms

フォリッジはInstanced Static Meshなので、CPUによるドローコールは上がりませんがかわりにBasepassによる単純なポリゴン描画コストが高いことがわかります。Basepassが高いということは非常に沢山のポリゴンを描画しているということになります。

では次にMaskedメッシュをNanite化しないままで計測した状態です。GPU 51.73 ms

予想出来たようにBasepassが低くなりましたが、かわりにShadow Depthsの数値が非常に上がっていることがわかります。これはおそらくMaskedメッシュが通常のメッシュよりも広い範囲のポリゴンを描画するため、動的シャドウがより広範囲に落ちることになるためこの部分の負荷が上がっていると予想できます。数が多い分、その効果が顕著にでている状態です。

次はOpaqueメッシュをNanite化したもので計測した状態です。GPU 19.74 ms

予想通り大幅にBasepassが落ちて、非常に軽量化されています!これであればゲームの中でも十分リアルタイムに使えるはずでしょう。Maskedメッシュとは違い、Shadow Depthsもほとんど上がりません。

そしてMaskedメッシュをNanite化したものを計測した状態です。GPU 103.39 ms

これは予想外の結果となりました…なんと非Nanite化したものよりも更にShadow Depthsの数値が上がっています。うーん、このままではちょっと使えそうにない…一瞬何かの間違いかと思いましたが、これは間違いなくNaniteでレンダリングされたMaskedメッシュです。

最後に公平ではありませんが、Nanite化してCast ShadowをオフにしたMaskedメッシュを計測した状態です。GPU 25.35ms

Shadow Depthsの値が下がったため、動的シャドウの影響は少なくなり、現実的な負荷へとなりました。これであればまぁ使えるでしょう。

結論

現状ではNanite化してもMaskedメッシュの負荷が一律で下がるとは言えません。あくまでも対応したという状態のようです。やはりまだまだMaskedメッシュは重たいと言えます。今後のアップデートでNanite化されたMakedメッシュが高速化される可能性は十分ありますが、現状ではOpaqueメッシュをNanite化して使うのが無難そうです。

今回の検証は何か間違いのある部分もあるかもしれませんので、あくまでも参考程度にお願いします。
検証方法におかしな点があればぜひご指摘ください。

追記

少し納得がいかないところがあったので、別のアセットでも試してみました。

interactive Open World Foliage in Props - UE Marketplace

こちらのアセットもMaskedマテリアルとなっており、形状的にもMegascans 草のアセットと似たものとなっています。他2つと比較してサイズが少し小さかったのでスケールを全て2倍にしています。

まずはNanite化する前の状態。 GPU 31.35 ms

そしてNanite化した状態。 GPU 44.44 ms

やはりNanite化すると、Shadow Depthsの値が上がるようです。Nanite化による原因でShadow Depthsが重くなるということは別の原因がありそうです。ということで原因を探してみることに。

現在動的な影のレンダリング方式はShadow Mapsによる影とVirtual Shadow Mapsと呼ばれる2種類の方式があります。

Naniteを利用する場合にはVirtual Shadow Mapsが良いと書かれていますが、TIPS内にはパフォーマンス上の落とし穴が多くあります、とも書かれています。

というわけで一旦通常のShadow Mapsに戻してみることに…
Nanite化したMaskedマテリアルでShadow Mapsに切り替えた状態。GPU 33.48 ms

Virtual Shadow MapsよりもShadow Depthsが下がってますね!!というわけで、Nanite化してもVirtual Shadow Mapsの負荷で思ったよりもパフォーマンスが出ないということがあるようです。

なかなかVirtual Shadow MapsがBetaとは言え、まだまだ難しいところがありそうです。