マテリアルレイヤー使用時のマテリアルアナライザーにおける「None」表示と誤った再ペアレント化の提案について

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

マテリアルレイヤー機能を使用したマテリアルインスタンスの構成について、マテリアルアナライザー(Material Analyzer)で解析を行った際の挙動について質問させてください。(添付画像ご参照ください)

  1. パラメータ表示の異常:
    1. 各インスタンスの「ベース プロパティのオーバーライド」は「0」ですが、「マテリアル レイヤーのパラメータ」列において、パラメータ名が表示されるべき箇所に「None」と表示され、その下に英数字の羅列(GUIDのような文字列、例:39F908ED...)が表示されています。
  2. 不必要な再ペアレント化の提案:
    1. 画面下部の「提案」欄にて、「以下の3個のマテリアルすべてに、同一のスタティックパラメータ配列があります」として、動的パラメータのみが異なるように再ペアレント化することを勧められます。しかし、実際にはこれらはパラメータを変更しておらず、既に適切な階層構造にあると認識しています。

【質問】

  1. マテリアルレイヤーを使用している場合、パラメータを変更していなくても内部的なID(GUID等)の違いにより、別々のスタティックパラメータセットとして誤検知される仕様、あるいは不具合でしょうか?
  2. 「None」および英数字が表示されるのは、マテリアルデータの破損等が原因でしょうか、それともエディタの表示上の不具合でしょうか?
  3. この「提案」が表示されたまま運用して、シェーダーのコンパイル数やパフォーマンスに悪影響はありますでしょうか?(実際に無駄なシェーダーが生成されているか懸念しております)
  4. この表示を正常なパラメータ名に戻す、あるいはこの警告を解消する解決方法はありますでしょうか?

​ご確認のほど、よろしくお願いいたします。

[Attachment Removed]

再現手順

  1. 添付のプロジェクトを開きます。
  2. メニューから「マテリアル アナライザー (Material Analyzer)」を開きます。
  3. 解析するマテリアルとして /Game/NewMaterial を選択し、解析を実行します。
    [Attachment Removed]

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

ご質問ありがとうございます。

また、非常に使いやすい再現プロジェクトのご提供、誠にありがとうございました。おかげさまで、詳細な調査を行うことができました。

結論から申し上げますと、ご報告いただいた症状のうち、「None」表記は仕様、誤った再ペアレント化の提案は不具合と考えられます。不具合に関しては暫定パッチをご用意しました。

以下、リスト化されたご質問の順番に沿って回答申し上げます。

> 1.マテリアルレイヤーを使用している場合、パラメータを変更していなくても内部的なID(GUID等)の違いにより、別々のスタティックパラメータセットとして誤検知される仕様、あるいは不具合でしょうか?

こちらは不具合となります。親マテリアルレイヤーのオーバーライド状況を管理しているエディタ用フラグを巻き込んでマテリアルレイヤーの不等価(!=)比較を行うという実装ミスが見つかりました。本来これらのフラグはオーバーライドの有無を判定する手がかりになるはずですが、単純な比較で判定を行う実装になっていたために、かえってオーバーライドを誤判定してしまった形です。

本件につきましては、準備が整い次第、社内のバグトラッカーに報告を行います。

また、正式な対応が行われるまでの問題回避のために暫定パッチを作成しましたので、お試しいただければと思います。

Engine\Plugins\Editor\MaterialAnalyzer\Source\Private\SMaterialAnalyzer.cpp の 1150行付近

	FMaterialLayersFunctions MaterialLayers;
	if (CurrentMaterialInterface->GetMaterialLayers(MaterialLayers))
	{
		bool bIsOverridden = false;
		if (CurrentMaterialInstance)
		{
			FMaterialLayersFunctions ParentMaterialLayers;
			const bool bParentHasLayers = CurrentMaterialInstance->Parent->GetMaterialLayers(ParentMaterialLayers);
+			bool bIsFullyLinked = MaterialLayers.EditorOnly.LayerLinkStates.Num() == ParentMaterialLayers.EditorOnly.LayerLinkStates.Num();
+			if (bIsFullyLinked)
+			{
+				for (const auto& LinkStates : MaterialLayers.EditorOnly.LayerLinkStates)
+				{
+					bIsFullyLinked &= (LinkStates == EMaterialLayerLinkState::LinkedToParent);
+				}
+			}
+			bIsOverridden = !bParentHasLayers || (MaterialLayers != ParentMaterialLayers && !bIsFullyLinked);
-			bIsOverridden = !bParentHasLayers || MaterialLayers != ParentMaterialLayers;
		}

> 2.「None」および英数字が表示されるのは、マテリアルデータの破損等が原因でしょうか、それともエディタの表示上の不具合でしょうか?

[Image Removed]パラメータノードなどと異なり、マテリアルレイヤーの実態は無名のマテリアル関数の一種であるため、アナライザーで表示可能な意味のある名前を求めることができず、やむをえず「決め打ちの"None"」と「シェーダ関連キー文字列」を出しているというのが実態となります。そのため、こちらについては不具合やデータ破損ではなく、「仕様」となります。

もし何か改善を行うとしますと、上記の回答で抜粋したコードブロックの直下のコードで仕込まれている FName() に何か混乱の少ない文字を与えて、少なくとも表示を「None」から切り替える(たとえば、""Material Layer"など)というアプローチが考えられます。

		CurrentMaterialNode->MaterialLayerParameters.Add(FStaticMaterialLayerParameterNodeRef(
			new FStaticMaterialLayerParameterNode(FName("Material Layer"),
				MaterialLayers.GetStaticPermutationString(),
				bIsOverridden,
				this->ParameterFilter)));

>3. この「提案」が表示されたまま運用して、シェーダーのコンパイル数やパフォーマンスに悪影響はありますでしょうか?(実際に無駄なシェーダーが生成されているか懸念しております)

今回の件につきましては、実シェーダーのコンパイル数やパフォーマンスには影響はなく、あくまでエディタ上の誤検出・誤提案と解釈していただいて差し支えございません。

前述のパッチを適用いただければ誤検出が抑制され、ひとまず「提案」も行われなくなります。

> 4. この表示を正常なパラメータ名に戻す、あるいはこの警告を解消する解決方法はありますでしょうか?

・パラメータ名に関しては元が無名であるため、大変恐縮ながら、適切な対応が困難です

・今回の誤警告に対しては上述のパッチで解消が可能です

となります。

以上、よろしくお願いいたします。

[Attachment Removed]

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

遅まきながら、社内のバグトラッカーに報告を行いました。

あわせて、Public Issue化の申請も行いましたので、承認後下記のURLより正式な対応の状況を追跡していただけます。

以上の対応をもちまして、本件は回答済みとして、一旦Closeさせていただこうと思います。

よろしくお願いいたします。

[Attachment Removed]