11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Unreal Engine (UE)Advent Calendar 2021

Day 10

[UE4] DynamicなShadowを何とか軽くしたい

Last updated at Posted at 2021-12-10

検証UE4: 4.27.1
まちがってたらごめんなさい。

はじめに

DynamicなShadowは、
Movableなライト。
Stationaryなライト+Movableなメッシュ。(Stationaryなメッシュも?)
等でShadowをCastしたい時に出ます。
負荷として積み重なり重くなる傾向にあるので、極力使わない方が良いのですが、それはそれとして時には使用せざるを得ない時が有ります。
(車のヘッドライトとか、手に持つ松明とか)

参考資料

こちらはShadowについて詳しい記事を書かれています。
是非読んでみてください。

解像度を下げる

Stationaryなライト、もしくはMovableなライトの場合、ShadowMapにレンダリングします。
単純にシャドウマップへのレンダリング解像度が下がればその分描画負荷が減ります。

個別にはライトの詳細欄で「Shadow Resolution Scale」を調整する事で解像度を減らしたり、解像度を増やす事が出来ます。
image.png

コンソールコマンドで一律で操作する

個別に操作するのが面倒な時は下記コンソールコマンドで、各ライトの種類に一律スケールできます。
(例えばカットシーンとかで描画負荷が高く、CastShadowのコストを削りたい時。もしくは逆に、カットシーンだけ高品質にしたい場合とか)

  • r.Shadow.TexelsPerPixel
    • StationaryライトのCastShadowの解像度スケール(対Stationary/Movableメッシュ)
  • r.Shadow.TexelsPerPixelPointlight
  • r.Shadow.TexelsPerPixelSpotlight
  • r.Shadow.TexelsPerPixelRectlight
    • こちら3つはMovableライトのCastShadowの解像度スケール

コマンドの内容的には、上げると使用する解像度が大きくなり綺麗に負荷高、下げると使用する解像度が小さくなり低品質に負荷安。

MovableなSpotLightで、"r.Shadow.TexelsPerPixelSpotlight 2.4" の時 1016x1016
image.png
"r.Shadow.TexelsPerPixelSpotlight 0.5" にすると 248x248に。影のくっきり感も減少。
image.png

WorldPositionOffsetを使うメッシュの注意

Movableなライトを使用したCastShadowでは、Static/Stationaryなメッシュは1度レンダリングするとキャッシュされて
次のフレーム以降は個別にレンダリングが走らないようになっています。

↓Staticな柱、Stationaryな球は1つ目のCopyCachedShadowMapバッチでキャッシュから再利用されています。
Movableなピラミッド、MannequinだけがShadowDepthのレンダリングが走っています。
image.png

動かないメッシュは1度レンダリングすれば使い回して大丈夫、との形です。
が、 WorldPositionOffsetを使用したマテリアルはStaticでもキャッシュに乗りません。

↓Staticな木のメッシュですが
image.png
キャッシュには無く、毎回レンダリングされています。
image.png

WorldPositionOffsetは頂点を動かす機能ですので、Movableと同じ扱いを受けるようになります。
森の中で車のヘッドライトとか、持って歩く松明とか大変な事になりますね!

MeshComponent内に一つでもあれば……

例えば、スタティックメッシュ内にマテリアルが複数ある状態で、
その中の 一つだけWorld Position Offsetを使用したマテリアルがある 場合。
下記は「M_UseWPO」マテリアルだけWorldPositionOffsetを使っており、残りは「WorldGridMaterial」なのでWPOを未使用です。
image.png
この場合、 該当のMeshComponent全てキャッシュに乗らなくなります!
image.png
このような形で使用する際は、WPOを使うマテリアル部分だけ別メッシュにした方が良いかもしれません。

対策

r.Shadow.CacheWPOPrimitives
のコンソールコマンドがあります。
これは、WorldPositionOffset を使用したマテリアルでもキャッシュに乗せるコマンドになります。
(デフォルト0で乗せない設定。1にするとキャッシュに乗ります)
ただし、1にすると CastShadow側のメッシュのWorldPositionOffsetが無効化されます。

キャッシュに乗せる代わりに、WPOを無効化してStaticな扱いにする形です。
↓途中で1に切り替えました。WPOで動いている葉ですが、CastShadow側だけ止まります。
a.gif

その代わり、無事キャッシュに乗って毎フレームレンダリングが走る事が無くなりました。
image.png

動的にON/OFFを切り替えれますが、そこそこのヒッチが発生する可能性があります。

ほか

  • 参考URL先にもあります通り下記コマンドとかでしょうか
  • Shadowに限らずですが、ライトパラメーターの「Attenuation Radius」も極力小さく……できれば……
  • ライトの影響受けなくて良いならLightChannelでCastShadowする対象絞れるかなぁ
    • メインのディレクショナルライトをChannel 1、MovableなPointLightをChannel 2にして、影響受けたい(DynamicにShadowを落としたい)メッシュだけchannel 2もONにする
    • と思ったけど、使い所あんまり無さそうなので備考欄行き。カットシーンの描画負荷対策で、見た目重要じゃないオブジェクト削るとかならまだ有り?

(WPO気をつけた方がいいですよ、的な事書きたかっただけの記事です)

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?