水に濡れて張り付いて透ける布

#え！？何を想像したんですか？？？

さて、こんな出だしですが真面目な記事です。
Houdini19.0からVellumにVellumFluidというモード？が追加されました。
これは文字通り布や毛のシミュ用だったVellumでFluid、つまり液体のシミュレーションが出来るようになったという事です。
一体SideFXはVellumをどうしたいんだ....そのうちVellumPyroとかしそうで怖い。

#概要
https://youtu.be/wX4ZAujOgvE
こんなのを作ります。

・Vellum Fluidの作成方法
・アクティブにglueを変更する方法

この２つが軸です。

**この記事は中級者を対象に書いています。**

初心者用記事も書きましたが、Vellumを1つ1つ説明してSolverの説明して....という、非常に長ったらしい読む気の失せる怪文書が出来たのでお蔵入りになりました。
一応、VEXが出てくるところや重要な箇所は解説を載せました。

#制作
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/07dfcf55-6352-c98c-f81b-52d193efccc3.png)
まずノード図です。
詳しくは後程説明します。

#布 (Vellum Cloth)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/10572ed6-f1c1-bbd1-aa4b-e418d7a43c19.png)
いつも通り制作します。
今回は固定と識別が必要なのでpinとgroupを指定してください。
ちなみに、こういう布を作る時はRemeshの前にグループ指定すると位置が変わらないでやりやすい。

#コリジョン用の豚 (Vellum Cloth)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/d75bae41-d324-f3a4-e406-9612178daddb.png)
今回、通常のコリジョンのように使用すると、張り付きのシミュレーションがうまくいかないので完全固定したVellumとして使用する。
pin to animationのgroupを 「*」 にすれば、全てのポイントを固定＝完全に動かなく出来る。
ちなみに、ここで動く物をコリジョンにしてpin to animationすれば動く物に布を張りつかせる事も出来る。

#水 (Vellum Fluid)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/53f48da7-c889-c875-7de6-6deb950637be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/2cdfd223-8b6f-ccab-af98-c90c598ead91.png)
Vellum Fluidの中身は非常に単純だ。Vellum grainsの物とほぼ同じだろう。
Create Points from Volumeをオンにしないと動かないので注意。

ここの設定は内部で使用するので、Fluid_GEO と Fluid_CON を出しておこう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/e652ea60-c4d0-3f88-450c-a52bb4db4fbf.png)
これらの設定したVellumを、GEOとCONに分けてMergeしてVellum Solverに入れる。

#Vellum Solverの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/f4268632-f084-28be-96c4-073c9391a995.png)
Vellum Solverの中に入り、**Vellum Constraints** と **Vellum Source** を出す。
これらをそれぞれFORCEとSOURCEに繋ぐ。
各ノードの設定を見ていく。
##Vellum Constraints
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/dfdd85bc-7653-4992-4c61-d689366a389f.png)
複雑に見えるが、変更する点は４つだ。

・Constraint Typeを**Glue**
・GeometryのGroupを**cloth (布のグループ)**
・Target Groupを**coll (コリジョンのグループ)**
・Create Constraintsを**Each Substep**

**解説**
まず、これは布がコリジョンに張り付く為のシミュレーションなので、当然ながらConstraintはGlueになる。
また、布を張りつかせるのでclothのみを対象にする為にgeometryでcloth groupを指定する。
そうなるとターゲットの指定が必要になる。これはcollのgroupだ。
最後に、全Substepで計算してほしいので、Constraintを作成するのをEach Substep(毎Substep行う)にする。

##Vellum Source
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/584852a2-1816-b215-d34c-e4a63789f3a6.png)
Vellum Sourceも同じく、変更する点は4つ。
こちらは水を出す為に行う。

・Activationを **$F<20**
・Emission Typeを **Each Substep**
・SOP Pathに **/obj/geo1/Fluid_GEO**
・Constraint SOP Pathに **/obj/geo1/Fluid_CON**

**解説**
まず、このノードは水を出し続ける為に作成している。
その為、いつ水を出すのかをしていするのがActivationだ。
今回は $F<20 なので、20フレーム以下の場合、水が出続ける。
次に、Emission TypeをEach Substepにした理由だが、そもそもSubstepとはSolverの計算を1フレームの中で何回区切って計算するかだ。つまり、Each Substepにしないと1フレームに1回しか水が出ない。
1/24秒に1回チョコチョコ出続ける水なんて変だろう。だからSubstepの中でも生成されるようにEach Substepにした。
最後にPathだが、ここは水がどれを参照するのかを明確にしている。
パスを指定しないと何を参照して水にするのか分からないからだ。

#シミュレーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/902e8405-87f5-2e2f-14e8-f2cf1362ba74.png)
とりあえずシミュレーションして結果を見てみた。
**Substepは10**で行っている。
通常の布が舞う物なら4~6程度で良いが、今回は間に挟まる布が伸びたりしてしまうので、10にした。
ここは各自のPCスペックとかけられる時間で決めてほしい。
自分は17分程度だった。(i9-7980XE)
キチンと張り付いていれば大丈夫。
もし張り付かない場合、Solver内部の設定が違うのでConstraintを見直すと良い。

##Deleteで布と水を分ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/93bc440b-a31d-d977-1212-7b567dfa07f0.png)
Vellum設定前に付けたグループを使ってDeleteノードで分けていく。
Groupを指定し、Operationを**Delete Non-Selected**にすれば、そのグループに属する物だけを取り出せる。

水も同じように水以外を消す。
ただし、水はPoint Groupなので**Entity**を**Points**に変更する。

#濡れている状態を保つ後処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/9cdd0dd3-7cd7-14e6-4352-f169f5c00e8a.png)
濡れている状態を保つのは後処理のほうが楽なので、後処理でやる。
Wrangleを繋ぎ、**布に @wet=0;**、**水に @wet=1;**のアトリビュートを付与する。
これは文字通り、布が濡れているか乾いているかのアトリビュートだ。
それぞれ、Solverの0入力と1入力に入れる。

##Solver内の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545265/cadf0109-196c-f2bb-2503-50aab0c80a56.png)
Solver内部に入り、Wrangleとattribute transferを上記の通りに繋ぐ。
Wrangleに**@P=point(1,"P",@ptnum);**と入力する。
これで位置を移動できたので、attribute transferでwet Attributeを伝播させたい距離だけ付ける。

**解説**
@P=point(1,"P",@ptnum);
ですが、これはポイントの位置を編集しています。
Solver内では外の情報とは別の処理が入るので、位置をシミュレーションした物に追従させる必要があります。
@Pはポイントの位置、point関数は 
point(入力、アトリビュート名指定、ポイント番号);
となっています。
つまり、ポイントの位置を現在のポイント番号と同じ位置にするという意味になります。

#まとめ
これで終了です。
あとはwetアトリビュートをMatに入れたり、色変えたりして透けさせてください。自分はKarmaXPUでうまくいかなかったのでAlphaに入れてFlipBookです。
Vellum grainsでも相当画期的で面白いですが、Fluidが来るなんて思ってもいませんでしたね。

最後にシーンを添付します。
https://1drv.ms/u/s!Al-gq6RIZjNr1SoBQ5-naOhdD6pE?e=uGRnOL
これは**動かないように何か所か変更してあります**。何の理解もせずただ持ってくだけ人が自分は死ぬ程嫌いなので。
変更してある点は記事内で触れている場所になります。
どうしても分からなかったら自分のTwitterにDMを頂ければ完成版のデータをお送りします。(https://twitter.com/TF_siri)

では、自分の記事はこれで以上になります。
ありがとうございました。


**Houdiniはいいぞ！！**