MobileForwardでTwoSidedMaterialのメッシュのDirectional lightの影部分の描画がおかしくなる

お世話になっております。

UE4.27.2のモバイルフォワードのレンダリング​環境において、特定のライトの設定でTwoDidedマテリアルの描画がおかしくなる不具合に遭遇しております。

Directional lightとSkyLightのMobilityをStationaryまたはMovableに変更し、「Preview Rendering Level/Android ES 3.1」で表示を確認すると添付画像のようにDirectional lightの影部分の描画がぱっきり切り替わってしまいます。

Lighting Onlyで確認するとライトの計算は正しそうですが、DetailLightingの計算がされたタイミングでおかしくなっていそうです。

こちらのマテリアルの用途として、植物の葉のような板ポリを組み合わせたメッシュに適応を考えております。​

Mobilityの設定は変更しない形で、解決策を模索しており対応方法のご助力をお願いできればと思います。

お手数をおかけしますが、ご確認よろしくお願いいたします。​

[Attachment Removed]

再現手順

  • EpicGameLauncherでUE4.27.2でBlankプロジェクトを作成する
    • Mobileを選択する
  • NewLevelで新しくレベルを作成する
  • ライティングの設定を変更する​
    • ​Light Source(Directional light)のMobilityをStationaryまたはMovableに変更する
    • SkyLightのMobilityをStationaryまたはMovableに変更する
    • [Image Removed]
  • ​TwoSidedのマテリアルを作成する
    • TwoSidedを「True」, BaseColor(1,1,1), Metallic(0), Specular(0), ​Roughness(0)
  • レベルに​「Sphere」を設置して、先ほど作成したマテリアルを適応する
  • 「Settings/Preview Rendering Level/Android ES 3.1」を選択する
  • ​「Sphere」の影部分の描画が添付画像のように、描画がおかしくなってしまう。
    • [Image Removed]

[Attachment Removed]

シェーダーの調査を進めたところ、

MobileBasePassPixelShader.usfにおいて、最適化のためかディレクションライトに向いていないメッシュの計算を省いている箇所を発見しました。

// Skylight
#if ENABLE_SKY_LIGHT
	//@mw todo
	// TODO: Also need to do specular.
	#if MATERIAL_TWOSIDED && LQ_TEXTURE_LIGHTMAP
	if (NoL == 0)
	{
	#endif
 
	#if MATERIAL_SHADINGMODEL_SINGLELAYERWATER
		ShadingModelContext.WaterDiffuseIndirectLuminance += SkyDiffuseLighting;
	#endif
		Color += SkyDiffuseLighting * half3(ResolvedView.SkyLightColor.rgb) * ShadingModelContext.DiffuseColor * MaterialAO;
	#if MATERIAL_TWOSIDED && LQ_TEXTURE_LIGHTMAP
	}
	#endif
#endif

こちらで行っている"if (NoL == 0)"の処理を外すことで、処理負荷は上がるものの上記のような描画ではなくなりました。(UE5.2以降ではこちらの判定はなくなっていそうでした。)

UE4.27.2での対応としては妥当性はありますでしょうか?

[Attachment Removed]

お世話になっております。詳細なご調査ありがとうございます。結論から申しますと、ご認識の通りで、対応として妥当と考えます。

ご提示いただいた箇所はUE4系のモバイルフォワードに残っていた古い実装で、TwoSidedかつロークオリティライトマップを使用するマテリアルに限り、スカイライトのディフューズをNoLが0のピクセル、つまりディレクショナルライトと反対を向いた面にのみ加算しています。このためNoLが0になる境界を挟んでスカイライトの寄与が不連続に切り替わり、今回のように影側との境目がぱっきり見えてしまいます。

片面マテリアルの場合、MATERIAL_TWOSIDEDが無効となり当該のif文自体がコンパイル時に除去されるため、スカイライトは条件なしに加算されています。したがってこちらのif文を外すことは、TwoSidedマテリアルの挙動を片面マテリアルと揃えることになります。当方でもUE5.5のリリースブランチを確認したところ、MobileBasePassPixelShader.usfのGetSkyLighting関数においてスカイライトが条件なしに加算されており、ご指摘の判定は存在しませんでした。現行エンジンの実装とも方向性が一致しますので、UE4.27.2への対応として問題ないと考えます。

留意点として、変更後はライトに向いている面にもスカイライトが加算されるため、対象のマテリアルは従来より全体的にわずかに明るくなります。負荷の増加はTwoSidedかつライトマップを使用するマテリアルのピクセルに限られ、ごく小さい想定ですが、念のためターゲット実機での計測をおすすめします。また、エンジン改変となりますので、今後エンジンをアップデートされる際はマージ漏れにご注意ください。

お手数ですが、よろしくおねがしいます。

[Attachment Removed]

ご確認ありがとうございます。

念のため、実機での計測を行いつつ対応の方させていただこうと思います。

調査にご協力いただきありがとうございました。

引き続きよろしくお願いいたします。

[Attachment Removed]