感覚でいじるDOP

## はじめに
数年ぶりのadvent calenderに急遽参加です。
今回はなんとなくでDOPをいじって泡を作ります。
hipファイルも共有します。

## 目的
* 水中の泡をつくる
* シンプルなセットアップを心がけてDOPをいじる
* [リファレンス1](https://stock.adobe.com/jp/video/sunbeams-and-bubbles-underwater/423056032?prev_url=detail)
* [リファレンス2](https://depositphotos.com/photo/water-bubbles-in-motion-127346308.html)

---------------------------------------

リファレンスを見ると、
* メインの大きな泡（赤線）
* その周りの小さい泡（青線）
* もっと小さい泡（緑線）

があるのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/ddd2c1e6-baad-1910-c7f8-1c0764014e42.png)

これら全部の要素を作るとなると記事が長くなるので、今回は特にメインの泡（赤の部分）だけをつくることにします。

## 作る前に考えたこと
まず、水中の泡を見ていると、張力がはたらいていそうな水の中なので、Fluid系のシミュレーションをすればいいかなと思いました。
FLIPはセットアップが面倒なので、パス。
POP FluidかVellum Fluidで何とかやってみよう、できなかったらFLIP使ってみようという感じでした。
また、Vellum Fluidのほうが安定しているイメージがあったのでVellum優先かなとも思っていました。

加えて、メインの大きな泡を見ると、ドーム型になっているので、Pyroつかってキノコっぽくすればいい感じになるかなと考えました。

## 作業
#### Vellum Fluidの簡単なセットアップをつくる
ソースのジオメトリを作って、簡単に変形、Vellum SourceにつないでVellum Fluidの設定をします。
VellumSolverにつないで、重力を0にし、風を与えて動作チェックしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/704ee4e5-6093-034c-ed4a-55146765609a.png)
![Up1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/2b108651-d29d-09ce-4482-0adb57fd5420.gif)
ちゃんと動いています。


#### Pyroで浮力を足す
Pyroでキノコ型ができるのは、temperatureによって上向きの力ができるからです。
真ん中のあたりは強い力が発生しますが、周りの部分は弱い力になるので図のようにキノコ型になるイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/c3b4c6a6-4936-078f-35f7-ec078e048e30.png)


これを利用します。パーティクルからtemperature fieldを作って、Pyro solverに入れてあげればいい感じのキノコ型をつくるvel fieldを得られるはずです。

まとめると、

1. パーティクルをボリュームに変換
2. ボリュームでPyroのシミュレーション
3. できたvel fieldでパーティクルを動かす

といった流れをDOP内で組みます。

上記ではvellum solverのwindに{0,1,0}の値を動作確認のためにとりあえずで入れましたが、pyroでできるvel fieldによって上向きの力が働くので{0,0,0}にしておきます。
また、DOP内でボリュームを作りたいので、vellum solver SOPでAllow Editing of Contentsをして限定解除して中でいじります。
DOPを一から作ったほうがきれいなノード群にはなりますが、手間がかかるのでvellum solver SOPをそのまま使っていきます。

vellum solver sopの中に入ると下図のようになっており、DOPがあります。(赤線内)
このDOP内で作業を進めていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/2a390eb0-b2dd-ae18-c68c-4fb4702f9fa3.png)

DOP内にはいると下図のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/90cfa780-2ad2-ec49-2f80-0dfd649cd1df.png)

ここでscaler field, vector field, multi solver等々を足して下図のようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/19440c51-5a8b-b6e6-a625-7de455f516c2.png)
(こんなになっちゃった..... たはは)

それぞれ、
赤枠　：　各種ボリュームデータ作成
青枠　：　vel fieldでパーティクル動かす＆調整
緑枠　：　Pyroシミュレーション


先ず赤枠部分 - 各種ボリュームデータ作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/ff0e3a99-102e-4be7-b05b-46fef8e7e2be.png)
sparse pyro solverを使いたいので、smoke object(sparse) ノードの中身で必要そうなものをコピーします。
smoke objectの中身は下図のようになっており、赤線部分が必要そうなボリュームデータを作っている部分。
青線部分がなんか必要そうな部分。細かい理解はしていませんが、必要そうだから使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/3b1d9538-2395-4af5-6999-27215e2efd44.png)
以上をrelative reference等に気を付けてコピーしてくるだけ。

青枠部分 - vel fieldでパーティクル動かす＆調整。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/c2017198-db38-ca65-9c06-094818b171a2.png)

pop wrangleではpyro部分でパーティクルからボリュームにデータを移すためにdensityとtemperatureを1として設定。
pop advect by volumeでvel fieldをつかってパーティクルを動かす。
pop steer cohesionは後述の調整のためにつなげる。
pop dragはパーティクルの上昇が速すぎないように。

緑枠部分 - Pyroシミュレーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/41a280fd-2c82-06ee-444d-57f27259ff3e.png)
gas particle to fieldをつかってパーティクルのdensity, temperature, vをボリュームデータに変換。
gas blurは後述の調整のためにつなげる。
sparse pyro solverでpyroシミュレーション。

#### 調整
物理的正確性を求められるシミュレーション解析を行っているわけではないので、**なんとなく** でノードを使っていきます。
正確であれば綺麗だということでもないので、自由にノードをつなげて調節します！

パーティクルがばらばらになってしまわないように、
* surface tension
* pop steer cohesion
を使います。
surface tensionはvellum configure grain SOPのノードにある値を強めに設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/f3a8c389-c352-9ed8-fef2-577c7c90e7a5.png)
pop steer cohesionノードでは、粒子同士がひきつけ合う力を加えることができます。
surface tension等、vellum fluidのパラメータの調整でも代用できますが、なんとなく追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/2ccbd351-8d16-6ff7-5dd6-3dd1bd51a5d5.png)




パーティクルからのvel fieldを滑らかにするために
* gas blur
を足します。
無くてもよい気がしますが、vel fieldがある程度滑らかなほうがパーティクルがばらけない気がしたので足します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/249d7964-00f6-bc8f-5c40-d1cb124c93e6.png)





## 結果と考察
![Up2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/ec8fd303-aa21-c02b-577b-9bada071947c.gif)
![Up3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/5cdd7f47-4097-d6f2-b133-0be64425706f.gif)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/904ac1d3-77a1-38a5-0a60-7ded2f5b97c4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186607/640db5cc-fda4-e14a-651e-485ac20b17e0.png)
カメラをよって見てみると良い感じにキノコ型になっているのがわかります。
あと、偶然ではありますが、大きい泡が崩れて中くらいのサイズや小さいサイズになっています。
これはパッと見良い動きになっているんじゃないでしょうか。

あとは中くらいの泡、小さい泡、ボリュームのシミュレーションをして足してあげれば完成。
大きめの泡をソース、コリジョンにしてPyroのシミュレーションをして、その結果でpop advect by volumeをつかったPOPで中小サイズの泡をつくってあげればいい感じになるかと思います。
vellum fluidを使っているので、コリジョンもつなぐだけでうまくいく...はず。

そして、カメラが近いショットには、ボリュームサイズを下げる、ポイント数を増やす、gas turbulence/gas disturbanceを加える、表面にノイズを加える等々をして細かい部分を作っていけばよいかと思います。

## あとがき
今回は、急遽参加を決めたので、なんとなくでDOP内をいじっていきました。
DOPでもSOPと同じように、"なんとなく組んだら動いた！"というくらい軽い気持ちでいじっていっていいと思います。
そして、DOPはSOPと違った楽しさがあるので、皆さんぜひ遊んでみてください。
 ~~最近はsolver系のノードもSOPレベルで完結していて使いやすくなっているので、もはや仕事には必要ない知識かも...。~~ 

 [HIPファイル](https://drive.google.com/file/d/1es_q3moLBbj8nJ-BdLiZg5Fpods1Rcgy/view?usp=sharing)