お世話になっております。
UI用マテリアル内でFmodを使った場合、0除算をチェックする ensure が発生してしまう場合があります。
調査した所、以下の条件が重なった時に発生するようです。
-
UIマテリアルを作成し、その中で Fmod の入力ピンに、Scalar と Vector2 など、型の違うものを繋げる。
-
Widgetを作り、その中にRetainerBox を置き、EffectMaterial に、上記のUIマテリアルを設定する。
-
GameMode等で、上記のWidget を生成し、AddToViewport する。
この条件を満たすと、ゲームをデバッグ実行した時に、
FGenericPlatformMath::FmodReportError() の中の ensure に引っかかってしまいます。
(エディタをデバッグ実行した場合、PIEやマテリアル編集中にも発生する事を確認しています。)
ensureMsgf(Y != 0, TEXT(“FMath::FMod(X=%f, Y=%f) : Y is zero, this is invalid and would result in NaN!”), X, Y);
FMaterialUniformExpressionFmod::GetNumberValue() 内でValueA、ValueB の R,G,B,A 全部を Fmod する
処理が書かれていますが、マテリアルのFmodの入力ピンBに入力したものが例えば Vector2 の場合、
R,Gには入力した値が入りますが、B,Aの値は0となり、0除算になってしまうようです。
そもそもマテリアル内で型の違う Fmod を使うのは避けた方が良いのでしょうか?
この現象を回避するにはどうしたら良いでしょうか?
(今は、エンジンソースを改造し、該当 ensure を回避するよう暫定対応しております。)
問題を再現するシンプルなプロジェクトを作りましたので添付します。
UE4.19.2で確認しております。
link text
お世話になっております。
本件返信が遅くなり申し訳ありません。
またサンプルプロジェクトのご提供ありがとうございます。
こちらでも現象を確認させて頂き、実装の方を確認させていただきましたが、
ご指摘いただいた状況どおりのようです。
除算に使用する値に対してキャストは危険かと思われるので、
明示的に0が入らないように型や値を入力するようにして頂く事をお勧め致します。
お手数おかけしますが、よろしくお願い致します。
明示的に0が入らないように型や値を入力するとは、添付した画像のようなマテリアルの作り方で宜しいでしょうか?
添付画像の通り、一見OKそうな方法でも、0除算が発生してしまう場合がありまして、その区別がよく理解できておりません。
- スカラー同士のFmodはOK
- 元々型が一致している値同士のFmodはOK
- Mask や MakeFloat* 等で変換したものはNG
と理解しておけば大丈夫でしょうか?
また、ensure が発生するのはプログラマがデバッグ実行した時で、マテリアル作成者が気づかずにうっかり作ってしまう事もあります。
もし0除算が起き得るパターンでFmod につないだ場合にWarning等を出すようにして頂く事を検討していただいても宜しいでしょうか?
お世話になっております。
値に関しましてはVector4同士、スカラー同士では問題ないようです。
そのためVector4に対して、使用していない箇所に1を入れておくといった対応になるかと思います。
今後の修正に関しましては、
4.20と21で確認したところ起動時に発生していたensureが発生せず、
何らからの修正が入っている可能性があり、現在確認を行っています。
何か分かり次第ご連絡させていただきます。
よろしくお願いいたします。
了解しました。
Fmodを使う時は、スカラー同士か、Vector4に変換してから行うようにします。
4.20 及び 4.21 で ensure が発生しない件については確認よろしくおねがいします。
お世話になっております。
本件お時間を頂いてしまい申し訳ございません。
調査を行ったところ、今回の問題に関連する変更点が多く調査に時間を要しておりました。
調査の結果ですが、まず今回Ensureが発生していたコードは4.20から走らない状況となっているようです。
これはGPUに渡す変数データのフローに大きく変更があり、
今回のようなfmodに関してはGPUで計算が行われるようになっております。
こちらはMaterialのシェーダーを表示し比較するとわかりやすいのですが、
Materialのノードで組んだfmodが展開されているのが見えるかと思います。
この時の適切なVectorの次元で計算が行われているため問題が発生していない、という状況となります。
上記修正が入っているSubmitはCL3932819となりますが、
変更量が多いため、4.19へのマージは難しい可能性があります。
前回お伝えしたような変換を行って頂くか、エンジンアップデートをご検討頂ければと思います。
お手数おかけしますが、よろしくお願い致します。
調査ありがとうございます。
4.20以降では ensure が発生しないという事で安心しました。
今後、4.20以降に更新する予定ですので、懸念は解決しました。
添付されたHLSLコードを確認しますと、スカラーとFloat2のFmodで、スカラーに丸められているように見えますが、これについてはマテリアルノードの組み方で回避できそうです。
4.20に更新したらマテリアルを組み、確認したいと思います。