UEでVDBファイルを検証した話

この記事は[Unreal Engine (UE) Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ue)の4日目の記事です。


この記事は、UE5.3になってから、扱いやすくなったVDBファイルをUEで検証したレポートです。
VDBファイルの書き出し方は、解説しません。検証には、サンプルのVDBファイルを使用しています。


# 確認環境
Windows 11 Pro
UnrealEngine 5.3.2


# VDBファイルとは

:::note info
VDBとはDreamworks Animationが提唱しているボリュームを表現するためのオープンソースのフォーマットであり、現在はHoudiniやRenderman、Realflowなどに組み込まれています。[引用元](http://modogroup.jp/tipsblog/volume/901_openvdb/#:~:text=VDB%E3%81%A8%E3%81%AFDreamworks%20Animation,%E3%81%AB%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
:::

と説明されています。ここで言う『**ボリューム**』とは、主に『**煙**』『**炎**』『**竜巻**』なと、StaticMeshやSkeltalMeshでは表現しにくい『**気体**』を指しています。
『気体』表現したい場合、UEでは、『Cascade』や『Niagara』等のパーティクルを使用するか、連番アニメーションをビルボードに張り付けて再生させる方法が考えられます。
どちらも、データとして軽いというメリットがありますが、3D表現としては物足りなく、立体感が無かったりします。また、ツール間でデータの橋渡しができなかったりする為、各DCCツールやゲームエンジンで**エフェクトを作り直し**が起こります。

# VDBの特徴

VDBファイルは、以下の特徴があります。

* 3Dワールド空間内で発生する
* 作成したソフト以外でも互換性のある(ツール間を跨げる)
* ベイクアニメーションが入っている為、ファイルサイズは大きくなる

綺麗な気体の表現できるが、尺が短いアニメーションでもファイルサイズは、大きくなってしまいます。
その為、ゲームではなく、映像作品での主に使用ケースが多いです。


# UEでVDBを読み込み手順

ここからが本題です。手順としては以下の手順で進めます。

1. VDBファイルをダウンロードする
1. 新規プロジェクトを作成する
1. VDBファイルをインポートする
1. マテリアルを作成する
1. HeterogeneousVolumeComponentを持ったアクターをレベルに置く
1. 4のマテリアルを5のアクターに設定する

:::note info
[チュートリアル](https://twitter.com/LambertTibo/status/1684631916622884864)を公開している人もいる為、記事と合わせて、参照してみてください。
:::

# VDBファイルをダウンロードする

テストに使用するVDBファイルは、[こちら](https://jangafx.com/software/embergen/download/free-vdb-animations/)を使用しました。
この記事では、『Ground Explosion』をインポートする想定で進めていきます。

![サンプルデータ_スクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/59e62f03-30c8-c85f-3107-76c47d630a0f.png)

まずは、Zipファイルを解凍して、『**.vdb**』をインポートします。

```
GroundExplosionVDB → ground_explosion → ground_explosion_VDB → ground_explosion_0000.vdb
```


# 新規プロジェクトを作成する

UE5.3以上で、新規プロジェクトを作成してください。

# VDBファイルをインポートする

インポート時に、専用のダイアログが開かれます。
『Ground Explosion』をインポートする場合は、以下のようになっています。

![OpenVDBインポートオプション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/2b94f43c-9443-2eb3-55f5-1bbe42e155bc.png)

『Ground Explosion』の場合は、これだと正しく動作しないので、以下のようにオプションを修正してください。

![OpenVDBインポートオプション_修正.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/e98ea291-4d9b-5da6-7af4-9a9ac81e985d.png)

インポートに成功すると、『AnimatedSparseVolumeTexture』が作成されます。

![インポートされたAnimatedSparseVolumeTexture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/1ef6b9fa-777f-bb97-58ac-28e9bb9fc522.png)


# マテリアルを作成する

続いて、マテリアルを作成します。Textureとしてプロジェクト内に生成される為、マテリアルでアニメーションさせます。

![VDBマテリアル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/11da8dc0-466c-c839-0dae-bead73fecb3a.png)

:::note info
このマテリアルの作り方は、先に紹介した[チュートリアル](https://twitter.com/LambertTibo/status/1684631916622884864)でも紹介されています。
:::

**SparseVolumeTextureSampleParameter**

このノードは、AnimatedSparseVolumeTextureを取り出しているノードとなり、このノードは、TextureSampleのように扱えます。

![SparseVolumeTextureSampleParameterノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/6efaf988-104c-4df2-c3c5-7367d221554a.png)

他にも、SparseVolumeTextureSample系のノードは存在していますが、ここでは、SparseVolumeTextureSampleParameterのみ挙げさせていただきます。

![SparseVolumeTextureSample系ノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/fe0fa8c3-7622-e3ba-67dc-65340baf49b3.png)

|TextureSample系のノード  |対応するSparseVolumeTexture系のノード|
|------------------------|-----------------------------------|
|TextureObject           |SparseVolumeTextureObject          |
|TextureSample           |SparseVolumeTextureSample          |
|TextureObjectParameter  |SparseVolumeTextureObjectParameter |
|TextureSampleParameter2D|SparseVolumeTextureSampleParameter |


# HeterogeneousVolumeComponentを持ったアクターをレベルに置く

AnimatedSparseVolumeTextureを設定したマテリアルを扱うには、『**HeterogeneousVolume**』を使用する必要があります。
HeterogeneousVolumeは、『アクタの配置』からも行うか、HeterogeneousVolumeComponentを持ったアクターを作成しても配置してください。

![HeterogeneousVolumeComponentを持ったアクターをレベルに置く.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/f1773be4-bb65-bfdb-caa5-20a63c4e34b7.png)


# マテリアルをアクターに設定する

作成したマテリアルを設定します。

![VDBのマテリアルをアクターに設定する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/b9ad810a-9b4c-8c1a-3c61-588b3c5a5ed9.png)

# HeterogeneousVolumeの制御

HeterogeneousVolumeの制御は公開されているパラメータから行います。
専用のパラメータの数は、かなりシンプルになっており、**リアルタイムに反映**されます。

![操作系公開パラメータ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/33c70a0c-794f-158f-8d13-c7f11798bcc2.png)

**FrameRate**
アニメーションのフレームレートを設定します。調整もできますが、アニメーションがチラつき始める為、基本的には**インポートのまま変更しない方**が無難です。

**StartFrame**
アニメーションの開始時間です。

**EndFrame**
アニメーションの終了時間です。

**Playing**
trueになっていれば、アニメーションが再生されます。HeterogeneousVolumeには、『Play』や『Stop』等が実装されていない為、この**フラグから制御**します。

**Looping**
trueになっていれば、**アニメーションがループ**します。


再生させるとこんな感じになります。(※画像は圧縮して劣化しています)
画像の場合は、Temperature(温度)を2000.0にしており、Temperatureは、高い数値を入れないと、赤く発光しませんでした。

![再生アニメーション_50%圧縮.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/fedab5f7-b9e6-a239-a8aa-9b33dff80678.gif)


# SparseVolumeTextureのビューア

実は、SparseVolumeTextureのビューアがあり、C++のクラスとして用意されています。
使い方自体は、ASparseVolumeTextureViewerクラスを、レベルに配置すればそのまま、使用できます。

![ASparseVolumeTextureViewerの様子.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/3ba53a0c-2a07-d31a-4504-da6034a373bb.png)

AnimatedSparseVolumeTextureを直接参照する為、VDBファイルのデータの確認するには、最適なツールであるかも知れません。
**色は付かず、黒くなってしまいます**が、VDBのアニメーションに使用される範囲が、**黒い半透明のボックスで囲われており、アニメーションの大きさが一瞬で分かります**。
また、操作できるパラメータがいくつかあり、HeterogeneousVolumeComponentよりも、AnimatedSparseVolumeTextureの中身を詳細に確認できます。

![ASparseVolumeTextureViewerの操作.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/71ba61c2-ca41-9937-c903-b10cfd1199b8.png)


操作可能なパラメータについては、あえて説明しませんが、名前から何に使うパラメータなのか、想像が付くと思います。

:::note info
C++での実装が気になる方は、以下の『ASparseVolumeTextureViewerクラス』や『USparseVolumeTextureViewerComponentクラス』を追ってみてくだい。
コンポーネントのクラスも用意されている為、独自ビューアの作成なども出来そうです。

:::



# その他

**属性の種類について**

サンプルデータを見てみた限りでは、『0.density(密度)』『1.temperature(温度)』『2.flames(炎)』を確認できました。

[こちら](https://www.technical-artist.net/?ak_action=accept_mobile&tag=tutorial)の方の記事を見る限りでは、結構種類が豊富みたいです。Houdiniをお持ちの方は、実際に試してみるといいかも知れません。

**VDBファイルの書き出しついて**

HoudiniでのVDBの書き出しについては、[こちら](https://qiita.com/renkiku/items/0df37294080ee75486b0)が参考になりそうです。



# 参考
https://forums.unrealengine.com/t/community-tutorial-unreal-engine-5-3-crea-tornados-impactantes-con-vdbs-en-minutos/1289414
https://www.youtube.com/watch?v=L9Zn0AgW3io
https://www.youtube.com/watch?v=-9mah5rzviQ
https://www.youtube.com/watch?v=AhWqmtc0T7s