【VisualEffectGraph+ Houdini】煙が広がるスプライトシートをHoudiniで作り、VisualEffectGraphで使用する

## はじめに
今回の記事では、Houdiniを使って作成した煙エフェクトをUnityのVisual Effect Graphで使用するまでの手順を紹介します。

以下はHoudini Apprenticeで作成した煙をUnity上で表示させたものになります。
![result_effect.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/57f6ad5d-08c8-d36b-8743-bc5c5c48c8d1.gif)

Houdini Apprenticeを使って煙をレンダリングしているため、ウォーターマークがついています。
Houdiniの有料ライセンスを使うとウォーターマークが外れます。

## 環境
Windows 10
Unity 2018.3.11f1
Houdini Apprentice 17.0



# Houdiniの作業
Houdiniを使って以下の煙のスプライトシートを作成します。
![6_smoke.rop_comp1.0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/25e5f0d4-573d-7616-e55e-c1f3ae8a9a54.png)

## 1. 煙のシミュレーションを追加
まずは基本となる煙のシミュレーションをHoudiniで作成します。

### STEP1. NetworkビューでSphereを作成
まずはNetworkビューで`sphere1`を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/0135001e-40d4-f144-413d-41363cf6c4a9.png)

### STEP2. Dry Iceを追加
`sphere1`を選択した状態でPyroFxシェルフの`Dry Ice`をクリックすると`sphere1`にドライアイスのシミュレーションが適用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/f2540479-7edc-d463-f7c2-36f00a7f2d8f.png)

球体から冷気が発生するようになりました。
![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/e55c561f-095c-f55b-03f7-3493b2e2a039.gif)


## 2. 煙の出現を最初のフレームに限定
`obj/sphere1`のUniform Scaleに ```$FF == 1``` と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/c3e2d92c-49d1-0f0e-e50f-a82144813008.png)

煙が最初のフレームでのみ出現するようになりました。
![frame_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/05c11998-008e-af2c-38d3-cf20bba1989a.gif)

## 3. 煙の密度・温度を変更
`obj/sphere1`の中にある、`create_density`のパラメータ(`density`, `temperature`)を以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/f23de0dd-0e55-6054-c624-b8563d1b0ec4.png)

`density`を増やしたことで煙が濃くなり、`temperature`を増やしたことで煙の落下が速くなりました。
![density.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/e5ece8fd-7153-c7dc-a410-e52429fa5486.gif)


## 3. シミュレーション領域のサイズを変更
`obj/pyro_sim`の中に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/5baf68d2-1cb1-d48e-a80f-f016908365cf.png)

`pyro`ノードのパラメータを以下のように設定します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/9a770fa3-e994-d895-8275-426c08abd99e.png)

地面にぶつかって広がるような動きになりました。
![close.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/21f5997a-49de-a634-ea10-68bcc672e57f.gif)

`Size`と`Center`はシミュレーション領域の大きさと中心座標を意味しており、
`Closed Boundaries`はシミュレーション領域の面を閉じるかどうかを意味しています。
今回は`-Y`にだけチェックを入れているのでY軸下向きの面だけ閉じています。


## 4. 煙の形状パラメータの変更
`pyrosolver1`の`Shape`タブのパラメータを以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/3dda312b-157f-b30b-0703-164f4796db94.png)

`Dissipation`を増やすことで煙が速く消えるようにし、`Turbulence`を増やすことで煙にゆらぎを与えています。
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/52531078-ba94-89b8-500d-583aaae9a83a.gif)

この煙を真上から見ると以下のようになります。
![result_up.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/f79b63eb-d920-2de2-a8ff-0cdc82d1aa31.gif)

今回、この真上から見た煙をスプライトシートとしてレンダリングしてみます。

## 5. カメラの作成
レンダリングを行うためにはカメラを配置する必要があります。

まずはobj直下に`Camera`ノードを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/c137e3a1-3a6d-5508-6129-aa1fc6250fa1.png)

カメラのTransformタブは以下のように設定し、上空から真下を見下ろすようなカメラにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/0dd4b6fb-ef66-43bc-f303-5199834f5893.png)

カメラのViewタブではResolutionを(128, 128)に設定します。
これにより、レンダリングで出力する画像データの解像度が128x128になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/0f414842-caef-a9e6-2500-89e6f8dde983.png)

## 6. スプライトシートの出力。
`Game Development Toolset`シェルフの`T Sheets`をクリックします、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/1d0cdb56-c2a0-1bd1-41d1-77dca49192b4.png)

参考リンク : <a href = "http://houdini.indyzone.jp/blog/game-development-toolset-について/">Game Development Toolset について</a>


out直下に`rop_texture_sheet1`が作成されるので、レンダリングを設定を弄って`Render`ボタンでスプライトシートをレンダリングします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/f25352d1-c1bd-bd8c-b6bd-b678c11629f8.png)

以下のようなスプライトシートが出力されます。(ファイル形式はexr)
![6_smoke.rop_comp1.0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/25e5f0d4-573d-7616-e55e-c1f3ae8a9a54.png)

補足: 
Houdini Apprenticeでレンダリングすると、レンダリング結果にウォーターマークが追加されてしまいます。
ウォーターマークを外したい場合は有料のHoudiniライセンス(Houdini Indieなど)が必要になります。

## 7. レンダリング結果のexrを加工してpngとして出力する
img階層へ行くと、`comp1`ノード(Image Network)があるので、これの中に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/f4567e75-824e-eb57-0435-1016a269ff3a.png)

`File`ノードに`ROP File Output`ノードを接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/befa41e2-516c-0936-318d-c64d38c4808c.png)

Fileノードには、先ほどレンダリングしたexrファイルのパスを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/b52067cd-4e71-d43c-abc9-86265d107bf2.png)

`ROP File Output`ノードにはpngファイルを出力したいパスを設定します。
`Render`ボタンをクリックするとpngファイルが出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/3376dfc1-08e1-3a71-1ddc-90bc62fbf189.png)

**以上でスプライトシートの作成は完了となります。**

次にUnity上へ移ります。

# Unityでの作業 
## 1. スプライトシートの取り込み
先程レンダリングした煙のスプライトシートをUnityに取り込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/09c22745-946f-109b-f188-f4144197d7e9.png)

## 2. Visual Effect Graph の作成
以下のようなVisual Effect Graphを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/a23afbd9-a2b7-649c-73fa-d93976899aaf.png)

### Spawnコンテキスト(パーティクルの生成)
毎秒1個パーティクルが生成されるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/0e4c9122-bb7f-381a-713f-d72a68c36ca6.png)

### Initializeコンテキスト(パーティクルの初期化)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/ab3fadd1-9bc4-179d-4da3-30f8001b2d0b.png)

### Updateコンテキスト(毎フレーム処理)
`Flipbook Player`ブロックを使ってスプライトアニメーションが再生されるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/e4bb330e-b3a8-1fef-545d-202420c18946.png)

### Outputコンテキスト(パーティクルの描画)
`Main Texture`の部分には先ほどのスプライトシートを設定します。
`Uv Mode` = `Flipbook` に設定することで、テクスチャがスプライトシートとして扱われるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/da9e751a-5c49-1cc4-3add-bcf2c7dcc365.png)\

## 完成
上記のVisualEffectGraphをシーンに配置すると、以下のような煙が広がるエフェクトが表示されます。
![result_effect.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/57f6ad5d-08c8-d36b-8743-bc5c5c48c8d1.gif)

ウォーターマークが邪魔ですね。(実際にゲームで使いたい場合は有料のHoudiniライセンスを使いましょう)