お茶を淹れよう

( ^^) _旦~~
インフルエンザで朦朧としてる中から失礼。

さて、昔お茶を飲む記事書いた人です。
(https://qiita.com/TF_siri/items/972d723e221a849575bf)

という所から簡単に自己紹介させてもらうと、業界4年目のHoudinistです。
最近はUnrealEngineも使います。何故か在学生に名前が知られてる謎の存在、それが私だ。

で、今回は題にある通り、お茶を淹れます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/9xg9oMb0Jns?si=kw79CpXIrtbjkg0Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
こんなのです。

なら昔のでいいじゃんと思いますが、昔のはただ流体シミュして色付けただけで、要素としてはかなり少なかったのでもっと要素を増したいな、と思ってるので作り直したかった感じです。
また、今回の記事は中級者～向けになると思います。初心者の方は何やってんだこれってなると思いますが、がんばってください。

# 作る要素
今回作る要素は主に
・お茶自体のfluid
・ティーパックのCloth
・ティーパックの紐のhair
・ティーパックのタグのMatchShape
・茶葉のMatchShape
・湯気のSmoke
・ミルクと紅茶の混ざり

をシミュレーションした後に
・fluidと茶葉の接触から滲む紅茶の色
・smokeから湯気の曇りを転写

を行い、レンダリングを行います。

また、作る要素としてお茶自体のFluidと、それを受けるティーカップ等がありますが、これは昔の記事
(https://qiita.com/TF_siri/items/972d723e221a849575bf)
をそのまま持ってきてるのでこちらを参考にしてください。

大まかなネットワークは以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/40f3bf7b-b85b-810d-3c05-308c3a7d4dd4.png)

青 ＝ 以前の記事ほぼ同じか単純なモデリングなので、今回使用した改変点のみの簡単な説明になります。
緑 ＝ Vellumを用いたシミュレーション
黄 ＝ 色の混ざり具合

になってます。
あとレンダリング系のTOP(Solaris)もちょっとやります。

# 液体のシミュレーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/751054a5-0678-d3f3-1420-d4f9a188d3e6.png)
今回は茶葉を躍らせる為にまず液体からシミュレーションします。
同時にシミュレーションして相互作用させる場合、ティーパックの布が水を貫通するが影響は少し受けるみたいな非常に難解で難しい設定が必要な上に、相互作用させる先は水で影響が非常に軽微なので別々にシミュレーションを行った方が都合が良いと判断したからです。

このネットワークではSwitchを使用して3つの入力がありますが、これはお湯を出している時、何も出していない時、ミルクを出している時で分ける為に使用しています。
Houdiniでキーを打つのはご法度だって？うるせぇ分かりやすくて制御しやすけりゃいいんだよ。

また、今回は紅茶とミルクの混ざり合いをシミュレーションしたいのでミルクの度合いをアトリビュートにして持たせてあります。

### Solver内
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/6ed97505-bd27-1883-3082-1a8c8d3ae3eb.png)
基本的には以前の記事と同じですが、MultiSolverを用いているので繋ぎ方に気を付けてください。
あとSubstepsをケチると結果変わるので気を付けましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/8c92e7bf-8ada-d0c4-60f0-b817bb9caca4.png)
SOPsolverの中はこのようになってます。
AttributeTransfarは文字通り付近にアトリビュートを伝播させるような挙動を行うノードです。
このMax Sample Countの数値が2以上だと、近いパーティクル同士で相互にアトリビュートが行きかうような、混ざるような挙動を再現できます。

このノードを用いてmilkアトリビュート、牛乳の混ざり具合を再現しています。

で、シミュレーションした結果がこちらです
<iframe width="560" height="315" src="https://www.youtube.com/embed/_euVMN_w9lI?si=xNlzAUn6NNvsr5kt" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
milk=0でオレンジ(紅茶の色)、milk=1で白です。

いい感じに混ざってますね。ではこの水に合った動きをティーパックどもにさせていきます。



# Vellumの設定、シミュレーション、小技
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/97ca17b4-4b69-8ab8-2167-01ed29238f0d.png)
以前のシーンからカップ持ってきて、ティーバック各種のモデリングを行いました。
モデリングの詳細な説明は省きますが、シミュレーションする物のポリゴンの濃さは同じぐらいにした方がなんかうまくいく事多いんで多分そうした方がいい。

ティーバック自体はシミュレーションにかけるので、要素毎にGroupをつけておきましょう。

さて、要素毎にVellumの設定をしていきます。
### Pack
cloth+Struts
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/108e6918-db33-6a63-6306-d0386102e8ff.png)
ティーパック本体はVellum Ballonを改変して作成します。
単純に布だけだと、三角形の形を維持するだけの硬さにするのが難しく、それを表現する為にSubsteps上げたりする程じゃなかったので、形状を保つ程度の弱いstrutsを入れています。

### Wire
hair
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/35b74336-2c78-32fd-bcff-1fd0346be184.png)
文字通り紐なのでhairです。
ちなみに、このちょっとクニって曲がってるのは折れ癖が付いてるとリアルかなってやったやつです。
このWireはかなり軽くしておかないとPackが引きずり出されるので、影響しない程度に軽くしましょう。0だとシミュレーションされなくなるので注意。

### Tag
shape match
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/ddcd530f-6581-70cc-f428-85eb7aaac891.png)
shape matchは知らない人も多いでしょう。自分もMardiniで初めて知った。
雑に言うとVellumでRBDsimが可能な感じです。変形しないVellumのシミュレーション。
紙のタグは変形しないのでShape matchでいいかなって。

この後Glueで付けるので分割はちょっと多めでやってください。

### Leaves
shape match
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/1deaeca8-5146-454a-2e5b-452ca68b08f1.png)
茶葉です。Packの中に入ってる。
これは最初Clothでやろうとしてたんですが、凄まじく重い上に動きもあまり見えないのでShapeMatchでシミュしました。
ちなみにコレを美しく動かすのが今回のキモになります。

### 接着
glue
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/f210bc4a-a67a-f0ce-86ba-9d33a240c049.png)
このままだとバラバラなので、glueで繋げます。
weldっていう絶対に離れない拘束もあるんですが、なぜかそれを使うと無限遠の彼方まで吹っ飛ぶ問題が起こりやすいので、自分は特別な理由がない限りGlue使う派です。
多分俺の使い方が悪い。

さて、これでVellumの全設定が完了しました。

シミュに入る前に小ネタです。
## 小ネタ 貫通を防ぐ
Vellumで色々やった方の中に、Clothで防いでSubstepも上げてるのに貫通してしまう、という問題に当たった方もいるでしょう。自分も今回茶葉流出が頻繁に起こりすぎて困ってた。
そんな方はVellumSolver → Advanced → Motion → Sliding Method を
【Traverse Triangles(Optimized)】にしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/732e7b3c-7de1-926f-f967-931720b3a499.png)
詳細な説明は公式の説明を参照してほしいですが、この設定がデフォルトだと凹部分は貫通するようになっていますが、Traverse Trianglesにする事で防げます。
(公式ページ＝https://www.sidefx.com/ja/docs/houdini/nodes/sop/vellumsolver.html)

このモードを使うときは全て三角ポリゴンになっているかどうかをキチンと確認してください。
まぁ不安ならDivide入れとけば自動で全部三角ポリゴンになります。

## 浮力
今回、水を別でシミュレーションして持ってくるが、その時に使うのがpopadvectbyvolumesというノードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/fecdc407-43d3-ab80-a2aa-16175b154e44.png)
これはVolumeのアトリビュートを参照してパーティクルの動きを付ける時に使用します。
例えば焚火で出てくる火の粉とか、あれの動きをシミュレーションする時に焚火の煙の動きを用いる事でリアルに煙に沿った動きで火の粉を動かす事が出来ます。

でもあれ？水はパーティクルの集合じゃん、と思った方鋭い。
(particleとvolumeの合わせ技だから厳密にはとか言うそこのアナタ、そんな上級者は読み飛ばしてくれ)

そう、そのままは使えないので、VolumeRasterizeAttributeでVolumeにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/ea105e79-ad49-5c0d-0bac-1ac68bfb183f.png)
で、ここで動きを持ってくる訳ですが当然だが水の中には浮力が生じる。
今回は茶葉が躍るようにしてみたいので、浮力の存在は必須だ。
しかし単純に重力を0にしたんじゃ通常時の動きが出来ず、Fluid+RBDみたいに相互作用も今回は事前シミュなので出来ないし、重力にキー打っても不自然だ。
水の中だけで浮力を与えたいなぁ......

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/70c815d4-b015-7195-be4e-f1e50e5b8909.png)
ハイ解決！！
そう、今回は水の動きを持ってくるわけですが、その水の動きに常に上向きの力を足す事で、水の中だけで上向きの力、つまり浮力が働いているように見えるんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/6353daa6-5fb0-79af-235a-366a2437546c.png)
では先ほど説明したPOP advect by Volumesに入れておきましょう。
Update VelocityでVelocity Blendを0.9とか強めにすると水の抵抗が強い感じに再現できてよかったです。

ではシミュレーションして見てみましょう。
最初にデフォ位置まで落とす事前シミュを50フレーム(約2秒)だけ入れています。
<iframe width="560" height="315" src="https://www.youtube.com/embed/9stWnp8of_c?si=DYmkdfhrNMWKCpuV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
 ** 茶葉が踊ってるぜ！！！ ** 

満☆足

さて、これでVellum系の設定とシミュが終わったので、最後に50フレーム移動させて要素ごとに分けてレンダリングで分かりやすいようにOUT_〇〇みたいな名前のNullを作っときましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/6ea6350a-0301-6d4b-0d0c-b6a3adebda6d.png)

# 茶葉からの色の滲出
知っての通り、茶の色は茶葉から出ます。
なので、茶葉から色が滲み出るのを表現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/e801e1e0-60d2-587f-dfbc-993eea1624ac.png)
こんな感じにアトリビュート付けてSolverに入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/6b2ae4d5-56c8-7228-e861-87362c654af2.png)
Solver内では、input1にsolverで計算した内容をコピーし、その後馴染ませを行ってます。
ちょっと馴染ませ部分が複雑なのは、レンダリング結果を調整する為に色が強く残るようにしたかったから。
Attribute Transfarを用いた方法だと、平均値まではできるんだけど茶葉みたいな常に色が出続けるやつに対してはあんまり向いてない感じしたので色が加算され続けるようにした。

さて、行った物がこちらです。
<iframe width="560" height="315" src="https://www.youtube.com/embed/mdINYzQP2ZQ?si=JbG5N23x6InRB5Rn" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
色は白が水、オレンジがお茶です。
いい感じに混ざってますね。

ではこれをどうやってレンダリングに持っていくかですが、Volumeにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/8783e1cf-ed70-8266-567f-af07f5750451.png)
こんな感じにteaとmilkそれぞれをVolumeにする事で、Volumeとしてレンダリングを行います。

ちなみにVolumeを見やすく100倍した物がこちら
<iframe width="560" height="315" src="https://www.youtube.com/embed/X6HH5UOFlVc?si=9eSg0bQJauYl1rLJ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
結構いい感じに見えるでしょう。
なんか残念そうな言い方なのはこの後のレンダリング編で語ります。

あとは液体をポリゴンにしたり、湯気をシミュレーションしたり、湯気によるカップの曇りをシミュレーションすれば完成。
この辺は以前の記事が詳しいので参照してください。同じ事やってます。

# レンダリング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/144257ae-0edd-82dc-e69c-6c401ad351f0.png)
LOP(Solaris)はこんな感じになってます。
まぁ普通に持ってきてマテリアル付けてるだけなので、その辺の細かい手順は省きます。
重要になりそうなマテリアルの解説だけ。

### Teapack
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/485d3372-55f7-1838-289c-ed2280d7fd30.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/4515945d-7a2c-502e-7e2a-0e4cfc9eeaab.png)
Copernicusの布フィルタをそのままいい感じの濃さにして、Alphaで透過してます。

### tea
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/39342d2c-6d79-5f4e-6485-f05b23fc59fb.png)
Density低めで影の色で出す感じです。
ここ反省ポイントなんですが、Volumeって不透明度で色を作るから、今回の紅茶のような「透明で色が付いている」を表現するには向いてないですね.....
一応似るようにはしましたが、解決する方法模索中。

### milk
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/161b01d6-1f42-bbcb-c6da-9ea1448d61bd.png)
VolumeのDensityを非常に濃くして牛乳のような不透明の液体感を出しています。
混ざり具合の都合もあるので見ながら慎重に決めてください。

### 液体
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/72ed3122-d256-42c6-f969-e14f2cfab999.png)
materialXのgeocolorノードでSOPのCdを持ってこれます。
これを用いて液体のポリゴンにteaアトリビュートを転写、色付けを行う事で表面から見た色の再現は可能
しかし、滲み出るお茶の色まで再現は出来なかった。

あとはいつもの感じです。

# おわりに
<iframe width="560" height="315" src="https://www.youtube.com/embed/9xg9oMb0Jns?si=kw79CpXIrtbjkg0Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
さて、長々と作ってきましたがどうでしょう。要素増えるとやる事多くて参るね。

レンダリング結果からも分かりますが、結構ノイジーになった事が心残り。
透明物2個とVolume3個重ね合わせだから当然なんだけど。レンダリング30時間かかったし。
あとこの記事再現するで全部シミュとレンダリングしたら自分のマシン(i9-7980XE+128GB)で大体50時間はかかるので、再現する場合は覚悟して作ってください。

まぁ、今回の記事ではVellumで貫通を防ぐ方法、AttributeTransfarの意外な使い方、浮力の作り方みたいな既存機能に頼らないで求める効果を得る方法とか、そういうのが学べたらいいんじゃないかなと思います。

不明点等あれば聞いてくれれば答えますよ。制作者なので。

恒例のシーン配布です。
いつもの通り自作発言とか、ちょっと改変してポートフォリオに入れるとかはやめてくださいね。わかるぞ。

シーン本体
https://drive.google.com/file/d/1zaCYXIwz4NmPxVYtBJLwCQr6q_DzkhGr/view?usp=drive_link

geo
https://109.gigafile.nu/0403-o2403cbc64638469ec5bcaa4fa8b2ec48
(2025年4月まで)

では最後になりますが、インフルで3DMU欠席した人からのアドバイス、健康には気を付けましょう！

よいお年を！！！