皆さんMassive Clouds使ってますか?
手軽にVolumeticな雲を描画するために有効なアセットです。
正直モバイルでいかほどの負荷になるか、まだ動かしていないので怖い所ですが、
次のネタで使ってみようと思ったので最近よく触っています。
そんな時にとある問題が発生&解決できたのでメモしておきます。
前提
本件は下記の環境で動作を行っています
- Unity2022.2.0f1
- URP 14.0.4
- Massive Clouds - Screen Space Volumetric Clouds 4.1.2
通常のMassive Cloudsの使い方通り、カメラのGameObjectにMainCameraタグをつけ、そこのMasssiveCloudsコンポーネントを張り付けて使用しています。
そしてUniversalRP上で使いたいのでMassiveCloudsUniversalRPScriptableRendererFeatureも追加。
まぁその辺りの使い方は公式マニュアルを読んで頂いて…
問題
今回はタイトル画面と、ゲームプレイ中の2つのMassiveCloudsコンポーネントを切り替えようとしていました。
タイトル画面はロード負荷を稼ぐために丸々非アクティブにして、ゲーム中においては退避しておくことにしました。
そしてPlayingシーンをAdditionalロードしておいて、ゲーム中はPlaying側のMassiveCloudsコンポーネントを使おうとした所…
何故か雲が表示されない…!
色々試したところ「Title側のMainCameraを削除しない限りは雲は全く表示されない」現象に悩まされました。
コンポーネントを見てもそれらしい箇所は見当たらず…いったい何故??
原因
という事で色々調査した所、原因はMassiveCloudsUniversalRPScriptableRenderPassでした。
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (currentMassiveClouds == null)
{
var massiveClouds = renderingData.cameraData.camera.GetComponent<MassiveClouds>();
if (massiveClouds == null)
{
var mainCamera = GameObject.FindWithTag("MainCamera");
massiveClouds = mainCamera?.GetComponent<MassiveClouds>();
if (massiveClouds == null) return;
}
currentMassiveClouds = massiveClouds;
}
if (!currentMassiveClouds.enabled) return;
CommandBuffer cmd = CommandBufferPool.Get(RenderMassiveCloudsTag);
currentMassiveClouds.BuildCommandBuffer(cmd, currentTarget, currentTarget);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
見た通り、currentMassiveCloudsに一度代入されるとcurrentMassiveCloudsのインスタンスが残っている限り、
最初に代入したcurrentMassiveCloudsがいつまでも残り続けるようになっていました。
ので一部だけを変更。
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (currentMassiveClouds == null)
{
var massiveClouds = renderingData.cameraData.camera.GetComponent<MassiveClouds>();
if (massiveClouds == null)
{
var mainCamera = GameObject.FindWithTag("MainCamera");
massiveClouds = mainCamera?.GetComponent<MassiveClouds>();
if (massiveClouds == null) return;
}
currentMassiveClouds = massiveClouds;
}
if (!currentMassiveClouds.enabled)
{
currentMassiveClouds = null; //←☆ポイントはココ。Disable時にnull代入して、描画時に再度インスタンスを確保しなおすように修正
return;
}
CommandBuffer cmd = CommandBufferPool.Get(RenderMassiveCloudsTag);
currentMassiveClouds.BuildCommandBuffer(cmd, currentTarget, currentTarget);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
こうする事で、disableになった場合に新たにカメラに付随したMassiveCloudsコンポーネントを確保することが出来るようになりました。
コンポーネント側のパラメータ設定が良くないのかなぁ??と思い色々試したのですが、RendererFeature(Pass)側に原因があったとは、盲点でした。
おわりに
という事で、かなりニッチな記事になってしまいましたが、MassiveCloudsコンポーネントをコネコネするのに時間を食ってしまったので、解決手法のログとして&ちゃんとRendererFeature側も確認するべしという反省として記事化しておきます。
あと、新バージョンのMassive Clouds Atmos も出ているらしいですね。
※何故か無料で取得出来た。セール中?それとも旧バージョン持ってるからかな?
※All Massive Clouds User can upgrade for a difference. との事で、旧バージョンを持ってるからっぽい
Atmosではこの辺りどうなっているんだろう?
またその内調査してみようと思います。