Commandlet起動からNiagaraアセットの画像取得

アセットの保存や共有などを目的に、そのサムネ画像やgifアニメを作る処理を作っています。

StaticMeshなどへの処理はCommandletからの呼び出しでもうまく作成できました。

そして、Niagaraのデータを元に動作フレーム毎に書き出してgifアニメに仕立てる処理を作ろうとしましたが、うまく出ませんでした。(添付:TestCommandlet.cppはアニメ化前段階のフレーム単位のpng保存としています)

エディタ上からEUW経由等で実行出来るようにして起動する分では、各フレームのパーティクルの様子が描画された画像が撮れるのですが、Commandletからの呼び出しで実行すると、パーティクルの描画が無い状態になってしまっています。

  1. テスト用に仕込んだ「 NiagaraComponent->GetSystemInstanceController()」がCommandletからの呼び出しではnullなので、Commandletからでは上手くNiagaraのシステムが立ち上がっていないor更新されていない事が疑わしいと考えますが、何か良い対処方法がありますでしょうか?
  2. Commandletからの動作後に「LogShaderCompilers: Display: Cancelled job 0x0000019B8EDD0A00 with pending SubmitJob call.」といったログが大量に出てしまうのです。何が原因でどういった対応が適当でしょうか?
  3. エディタ上での動作確認の際に、エディタ起動後1度目の実行時はパーティクルが映らず、2度目以降の実行だとパーティクルが映ります。キャプチャ前に何かしらの完了を待つ対応が必要になるのでしょうか?

これらに対して原因と対応をご教示いただけると幸いです。

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

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

長らくお待たせしております。

3.について原因が不明なのですが、今のところの見解をお伝えさせて頂きます。

>1.テスト用に仕込んだ「 NiagaraComponent->GetSystemInstanceController()」がCommandletからの呼び出しではnullなので、Commandletからでは上手くNiagaraのシステムが立ち上がっていないor更新されていない事が疑わしいと考えますが、何か良い対処方法がありますでしょうか?

ご指摘の点を含め幾つかの処理が不足していたようです。

追記したコードを添付しましたので比較してみて下さい。

>2.Commandletからの動作後に「LogShaderCompilers: Display: Cancelled job 0x0000019B8EDD0A00 with pending SubmitJob call.」といったログが大量に出てしまうのです。何が原因でどういった対応が適当でしょうか?

手元で同様の現象を確認できなかったのですが、添付したコードをお試し下さい。

シェーダーのコンパイルに関する処理が追加されておりますので発生しなくなっている可能性があります。

>3.エディタ上での動作確認の際に、エディタ起動後1度目の実行時はパーティクルが映らず、2度目以降の実行だとパーティクルが映ります。キャプチャ前に何かしらの完了を待つ対応が必要になるのでしょうか?

シェーダーコンパイルの問題かと思いましたが今回の変更では対処できておらず、今のところ原因不明です。

引き続き調べてみますが時間がかかる可能性があります。

効率は悪いですが、運用によっては単に二回連続で実行してしまうような措置も考えられるでしょうか。​

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

ご回答ありがとうございます。

頂きました差分を適用する事で、Commandletからの動作で、Niagaraでパーティクルの生成画像キャプチャが出来ました。

ただ、対応後に、下記の様に別のデータに対して動作させて試してみた所、

~2、~3 だと、Niagaraエフェクトが描画されず、

~4だと矢印は描画されるのに、丸のエフェクトが描画されない結果となりました。

~5では白い丸が半透明で薄くなっているので、色操作がうまく反映されていないのかと思われました。

ただ、~5で上向きに矢印が放出されるのですが、~4と同じ矢印素材を使っているようでしたが、色が付いていませんでした。(エディタ上のプレイヤーでも白かったので、そういうもの?)

何かまだ設定が不足しているのでしょうか?

それともNiagara側ではなく、レンダラやキャプチャ周りの設定不足だったりするのでしょうか?

const FString NiagaraAssetPath = TEXT("/Niagara/DefaultAssets/DefaultSystem.DefaultSystem"); const FString NiagaraAssetPath2 = TEXT("/Niagara/DefaultAssets/Templates/BehaviorExamples/RenderTargetTexturePainter.RenderTargetTexturePainter"); const FString NiagaraAssetPath3 = TEXT("/Niagara/DefaultAssets/Templates/Systems/AttributeReaderTrails.AttributeReaderTrails"); const FString NiagaraAssetPath4 = TEXT("/Niagara/VectorFields/VectorFieldVisualizationSystem.VectorFieldVisualizationSystem"); const FString NiagaraAssetPath5 = TEXT("/Niagara/DefaultAssets/Templates/Systems/SimpleExplosion.SimpleExplosion");重ねてご確認いただければ幸いです。

>3.エディタ上での動作確認の際に、エディタ起動後1度目の実行時はパーティクルが映らず、2度目以降の実行だとパーティクルが映ります。キャプチャ前に何かしらの完了を待つ対応が必要になるのでしょうか?

こちらに関しては、運用でカバーも可能ではある上、Commandlet からの動作では発生しないようなので、

今のところ優先度は低いです。

ただ、意図していないというか​望んでいない挙動なので、せめて原因​が掴めておけばとは考えています。

サンプルありがとうございました。

懸念していました色が付かなかった件など解消されたキャプチャ画像が撮れていましたし、

差し替えも出来ていました。

ただ、こちらのような挙動にする処理をCommandletからのC++処理で行う事は無理なのでしょうか?

手元でまずはキャプチャ動作をと考えて組んでみましたが、

QueueSubsystem->RenderQueueWithExecutorInstance

の処理を実行した所でエラーになっていました。

設定等が不足していたのでしょうか?それとも考え方から間違っているのでしょうか?

情報を頂けましたら幸いです。

(プロジェクトは D:/UDN/ に配置想定です。)

---

また、目標としては、下記のところまでを考えています。

1)NiagaraSystemアセットを動的に変えてキャプチャを行う

2)NiagaraEmitterアセットを取ってきて、既存もしくは新規のNiagaraSystemに配置して、キャプチャを行う

1番の分は頂いたサンプルに沿った情報で、取り回し方で引数の対応で実現可能そうですが、

2番の分も起動時の引数指定でどうにか出来たりするものでしょうか?

先日添付のプロジェクトに手を入れて、エディタ上からであれば

NiagaraSystemアセットを差し替えてキャプチャ出来る状態にしました。

(それでも初回実行時はNiagaraデータが差し変わっていないようでしたが・・・)

Contentにある NewEditorUtilityWidgetBlueprint のEUWのボタンからで起動できます。

Commandletからの起動で、RenderQueueWithExecutorInstance で落ちているようです。

バッチファイルでの記載の様に、-NiagaraPath= の後に差し替えパスを指定しています。

お手数かとは思いますが、こちらを参照いただけると幸いです。

ありがとうございます。色々とお手数をお掛けしました。

直接的にCommandletからの処理でキャプチャは出来ませんでしたが、

先に例示していただいたキャプチャの方法をCommandletからの呼び出しで

動作させることが出来ましたので、こちらで対応していきたいと考えます。

また、NiagaraEmitterの件は、キャプチャ用にダミーのNiagaraSystemアセットを用意しておき

それのEmitterを差し替えて保存し、そのアセットを上記の手順でキャプチャする事で

対応を進めていこうと考えております。

ひとまず本件はクローズとさせていただきます。

エンジンのループに依らないレンダリングに関しては参考にできるものが少なく、今のところ答えを得られていません。

今回挙げて頂いた NiagaraSystem についてクリアしたとしても別のものについては上手くいかないといった事態も考えられます。

コマンドライン始動でレンダリングを行うことが要件であれば MovieRenderQueue も適しているように思いますが、こちらを使用することをご検討されてはいかがでしょうか。

https://dev.epicgames.com/documentation/ja-jp/unreal-engine/using-command-line-rendering-with-move-render-queue-in-unreal-engine

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

参考までに、MRQ を利用したサンプルプロジェクトを添付しておきます。

Capture.bat​ 内のエンジン及びプロジェクトパスを変更してお試しください。

末尾​部分で表示する NiagaraSystem を変更できます。

停止部分まで確認した限り MRQ によるレンダリング処理は少なくとも Window, Slate に依存しますので Commandlet からは扱えないかと思います。

参考までに、停止部分までのコールスタックを添付しておきます。

[Image Removed]

MRQ 以外においても EngineLoop に依存した処理については Commandlet で正常に動作させるためのハードルが高い(LaunchEngineLoop.cpp を参考にしてみて下さい)ため、MRQ のコマンドラインレンダリングをベースに考えることをお勧めします。

https://dev.epicgames.com/documentation/ja-jp/unreal-engine/using-command-line-rendering-with-move-render-queue-in-unreal-engine

>2)NiagaraEmitterアセットを取ってきて、既存もしくは新規のNiagaraSystemに配置して、キャプチャを行う

こちらについては別の話題かと思われますのでこのスレッドでは扱いませんが、

FNiagaraSystemToolkit::InitializeWithEmitter

FNiagaraEditorTestUtilities::CreateTestSystemForEmitter

UNiagaraSystemFactoryNew::FactoryCreateNew

等に NiagaraEmitter を入力して NiagaraSystem を生成する例があるようです。

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

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

本件はクローズいたします。

また何かありましたらお問い合わせ下さい。