LoginSignup
2
2

More than 1 year has passed since last update.

[UE4]Distance Field Shadowが落とせない対象と、何か落とす方法

Last updated at Posted at 2022-02-26

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

はじめに

メッシュへの距離情報からShadowを落とすDistance Field Shadowについての話になります。
ゲームだと遠方の影をCascade ShadowからDistance Field Shadowにして負荷軽減したり、精度を上げたりするような時に使ってるかと思います。

ただ、このDistance Field Shadowでは落とせないメッシュがあったりします。
image.png
その場合、Cascade ShadowとDistance Field Shadowの境目で影が切れてしまい格好悪い感じになってしまいます。
なんとかしたい。

まとめ

(いつも長いと言われるので先に)

  • Distance Field Shadow で落とせるのはStaticMeshのみ。
  • ステーショナリーライトのInset Shadow For Movable ObjectsでムーバブルなMeshの影を落とせる
  • メッシュ設定のInset Shadowでメッシュ個別に影を落とせる
    • ムーバブルなライトならどのメッシュからも影を落とせる
処理方法 StaticMesh
スタティック
StaticMesh
ムーバブル
SkeletalMesh SplineMesh
スタティック
SplineMesh
ムーバブル
Distance Field Shadow × × ×
Inset Shadow For Movable Objects
(ステーショナリーライトのみ)
× ×
メッシュのInset Shadow
+ステーショナリーライト
× ×
メッシュのInset Shadow
+ムーバブルライト

スタティックなSplineMeshが厳しい。背景配置で多様するだろうし……
メモリが許せば全部StaticMesh化するのが良いのだろうけど、流石に。
何か出来ないかと試した結果で #Distance Fieldだけを生成したい だけど、SplineMeshに汎用近似メッシュ合わせるのはすこし厳しいか……

Distance Field Shadowで落とせない影

image.png
Distance Field Shadowですが、SkeletalMeshとSplineMeshは影を落とせません。
と言いますのも、SkeletalMeshとSplineMeshはDistance Field Shadow描画の元となるDistance Fieldが生成できません。
image.png
こちらがDistance Field。SkeletalMeshとSplineMeshからは生成できません。
Distance Field自体が変形できない為、変形するメッシュには追従できず反映されません。

とはいえ何も出てないのは格好悪いのでなんとかしたい……

ステーショナリーライト:Inset Shadow For Movable Objects

image.png
ステーショナリーなライトでのみ使用可能です。
この機能は、「ムーバブルなオブジェクトはInset Shadowを利用して影を落とす」形になります。
Inset Shadowとは?となりますが、これはオブジェクト個別にShadow Mapを生成して影を落とす事になります。
詳しくは下記Pre Shadow項目に詳しく書かれています。参照してください。
[UE4] Shadow Rendering(影描画)機能入門-PreShadow項目

image.png
ライトの可動性がステーショナリーな場合は、Inset Shadow For Movable Objectsがデフォルトで有効になっています。

image.png
今回の場合、ムーバブルなオブジェクトがこのように一つずつShadow Map生成されています。

その分、ムーバブルなオブジェクトが増えれば負荷が増えることが想定されます。
逆にデフォルトでONになっているので、遠景のムーバブルは影要らない!の時はOFFにするいい思います。

メッシュのDynamic Inset Shadow

image.png
前述のInset Shadow For Movable Objectsのメッシュ側のフラグになります。
Inset Shadow For Movable Objectsはライト側の設定で、ONにすると全てのムーバブルなメッシュに対して処理を行うのですが、こちらはメッシュ側の設定なので、このメッシュだけInset Shadowを使う!等が出来ます。
また、違いとして下記のようになっているようです。

  • ステーショナリーなライトの場合は、ムーバブルなメッシュのみInset Shadowが使用可能
  • ムーバブルなライトの場合は、スタティックなメッシュでもムーバブルなメッシュでもInset Shadowが使用可能

image.png
設定はMeshComponentの設定に有ります。

image.png
こちらも一つずつShadow Mapを生成しますので、多数をONにすると負荷が増える事が想定されます。
目立つメッシュや、カットシーン中はONにするとかでしょうか。

Distance Fieldだけを生成したい

頑張ったけどいい感じには出来なかった。
人型には難しい。負荷的にはちょっとだけエンジン弄る必要ありそう。
メモとして残しておきます。

Inset Shadowを使わず、Distance Field Shadowの仕組みを流用してそのまま影が出せないか、という所でDistance Fieldのみを生成する方法が無いか試してみました。

image.png
特に車とか乗り物はタイヤを動かすためだけにSkeletalMeshにしている事があり、その為にDistance Field Shadowが使えず勿体ない感じがします

今回はSkeletalMeshComponentの位置に合わせて、近似的なStaticMeshを使用して代用する方法を試してみました。
b.gif
結果はこちら。カメラが離れた時がDistance Fieldです。
(ちょっと近似的なメッシュを作らず、横着してCubeを使用しました。きっちり形合わせたい場合は車の形そのままのStaticMeshを用いれば良いかなと……)

やった手順

  • DistanceFieldだけ生成したいStaticMeshを配置。今回はCubeで代用
    • image.png
  • MeshComponentのオプション設定
    • コリジョンをOFF
      • image.png
    • ライティング周り
      • image.png
    • レンダリング周りで通常のViewには影響が出ないように各種OFFに
      • image.png
    • ここまでの設定で、通常のViewには影響を与えず、Shadowのみ落とす表示が出来ます
  • 現状だとカメラが近い所のCascade Shadow時にも描画されてしまうのでマテリアルを差し替えます
    • Maskedマテリアルで、Shadow Pass SwitchでShadowパス(Cascade Shadowとか)のみ0にして表示消します
      • image.png
    • 作ったマテリアルで置き換えます
      • image.png
  • これで、見た目上はDistance Fieldにのみ影響を与えるメッシュ配置になります。

問題として、
image.png
モーションには追従しないので、人形状等は難しいかも。
(やるとしたらCapsule Shadowみたいに各ボーンにメッシュくっつけて追従させるとかしか……)
image.png
DistanceField用Meshが元メッシュの形状からはみ出ると、元のメッシュにも影を落としてしまうので難しい。

※また、この方法だと画面には表示はされないもののCascade Shadow範囲内に入った際に、このメッシュもCascade描画が走ってしまう問題がある。
低コストマテリアルとはいえ負荷に。Inset Shadowとどっちが負荷的に良い?

この辺りも回避するにはエンジン改造するしかないかも。以下エンジンコード側の話メモ。
CastsDynamicShadowがONでないとDistanceFieldに積まれない。
けどCastsDynamicShadowがONになるとCascade Shadowにも積まれてしまう。
何かDistance Fieldのみ積む用フラグを追加して、FDistanceFieldSceneData::AddPrimitive 辺りでCastsDynamicShadow無視して積めばいけるかも。
未検証。

2
2
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
2
2