おじいさんの亡霊を制作する上でつまずいたところなど

# 概要
Houdiniでおじいさんの亡霊FXを作っていく中で、
つまずいたところや思ったことなどを書きたいと思います。

# 作例
![Grandpa Ghost V001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/f8f58b44-ff4a-eb96-a8c0-e846974463fc.gif)
※Glowはコンポで足してます。

## hip
https://www.dropbox.com/s/j4kvzeei3kofs8a/Grandpa_Ghost_forShare.zip?dl=0
※おじいさんの写真は権利関係のため付属しません。代わりにかわいいイラストを入れてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/2dd20e04-6f30-b371-e717-96f37469abf2.png)

##環境
Houdini Indie 18.5.351

# 下準備 - 写真を加工する
まずは亡霊化したいお好みの写真を、Houdiniで使いやすいように加工していきます。
![Fotolia_52825114_M.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/8a8630eb-bde8-69af-83c1-60b092580b65.jpeg)

自分は今回、なんでか知らないけどむかし購入していたおじいさんの写真素材を使うことにしました。
ただ人物に限らずハンバーグとかでも楽しいと思います。

用意できたらテクスチャとして扱いやすい形にしていきましょう。手順としては以下の3つです。

* 背景を消す
* 1024px * 1024pxなど2の累乗の正方形の解像度にする
* カラー素材とマスク素材の2つ用意する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/729f30e6-d85c-39f5-aea9-d54ad0b8a444.png)

# 中心のおじいさん
ここからHoudiniでの作業になります。まずは亡霊の中心に立つおじいさんを制作します。
この作業で目指す状態とノードはこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/abb8bb58-35a3-2fec-c300-bf9bdbe1ac72.png)



もうなんの説明もいらないほどシンプルなネットワークです。
なのでここではつまずいた部分、疑問に思った部分に絞って書きます。

## HoudiniのプリミティブオブジェクトにはUVがない
まず不思議に思ったのは、GridやSphereなどのプリミティブオブジェクトが
初期値でUVをを持っていないことでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/b87f6b53-845d-95d7-14d5-ecdb62660d11.png)
左：Gridだけ。UVなし。
右：UV TextureをつなげてUVを生成したもの。

このようにGridの後にUVTextureノードを接続して明示的にUVを作成しないと、
Materialを適用してもTextureが表示できません。


### なぜ最初からUVを持っていないのか？
これ、ある程度Houdiniに慣れると気にもしなくなるんですが、
Mayaなど他CGツールに慣れていると「なんで？」となります。はい、なりました。
作成時にUVもあるのが当然の世界で育ってきたので…。

じゃあなぜHoudiniではいちいち作成する必要があるのかというと、
個人的には**「使わないかもしれない情報は無闇に持たさない」**のが理由だと思っています。

MayaではUVはUVエディターを開いたときだけ見える情報ですが、
HoudiniではUVやPositionなどの情報（Attribute）を駆使して作業していきます。
そのときに使わない情報がたくさんあると、必要な情報を見つけづらいし、
データとしても重くなったりするからじゃないかなー、とおじさんは思います。

## Textureが逆さまになる
Material Paletteからconstantを作ったら、mat階層でそのconstantの
Color MapとOpacity MapそれぞれにTextureを適用します。
これでおじいさんが画面に出るはず。しかしなぜか上下逆さまです。なんで？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/fc223f80-1cf2-4191-ed43-9b471b32a545.png)

### Gridの起点とUVの起点が違う
Point Numberを表示するとなんとなく理由がわかりました。
Pointの開始番号0が、Viewでは左上から始まってるのに対し、UVでは左下から始まっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/ce3316f1-0627-46d9-ea14-4ee0865d5cc0.png)

つまりView上では逆から見ている、ということなので、UV Transformノードで反転すれば解決します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/a5ccd426-44a0-68ca-d5ee-564e3d67955f.png)


ただなぜGridが左上基準なんでしょうか？
この辺り深すぎる理由がありそうなので今回は考えないことにします。誰か教えて！

<details><summary>View上でAlphaが抜けない場合</summary><div>
constantノードのOpenGLタブから、Use Lightingをオン、
OGL Alphaを1以下（0.999とか）にすると解決することがあります。
それでもダメな場合は、Enviroment LightなどLightを1つ追加すると直ることがあります。

これに関しては理由はわかりません。これも誰か教えて！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/728d2262-6edc-43c3-005b-309b74c759ff.png)
</details></div>


# 亡霊のおじいさん
それではメインの亡霊おじいさんの制作に入ります。
最終的な状態はこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/17f34c05-54bf-a4a8-ed06-ea4da16412db.png)
これまた逐一手順を書いていくとめちゃくちゃ長くなるため、
作業してて注意が必要だった点、ハマった点について書いていくことにします。

## VOPでUVを参照するときは、UVをPointに持たせておく

おじいさんの根本をすぼませて幽霊のような形状にするのに、
VOPでUVを参照してPointを操作することにしました。
そのためにまずUV Textureで重要な設定があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/5316a563-223b-2bb0-8cd5-f5b033572dd9.png)

これをするとUV TextureノードのAttributeがPointに生成されます。
初期値ではVertexになっているので変えておきましょう。

なぜかというと、Pointを操作するために作ったVOP（Point VOP）では
基本的にPointのAttributeを参照するためです。
Vertexを参照することもできますが、ひと手間かかることになります。
今回は単なるUVの参照なのでシンプルにしておきます。

これ滅多に忘れないとは思うんですが、Texture表示のためだけに
作ったUVで作業していると意外と忘れます。
そうなると「UV持ってるはずなのになんでぇ！？」と
鼻水垂らしながら叫ぶことになるので気をつけましょう（経験談）。

※Point操作でUVを使った後は、Vertexの方にUVを戻したほうがTexture表示という本来の用途からすると正しいかもしれません。

<details><summary>**湧き上がる「最初からPointにUVを持たせておけばいいのでは？」という疑問**</summary><div>
これは会社のHoudiniマスターに教えてもらって初めて自分でも納得できた話なんですが、
通常はVertexに持たせておくほうがいいそうです。

なぜかというと、Mayaとかほかソフトが通常そうだから…というのもありますけど、
一番の理由は”PointだとUVをカットできない”からです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/a0da20e0-6c54-ad47-63fe-5f85896fa6ee.png)
pigheadはVertexにUVを持っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/e8f614e6-6bc8-10f8-ca07-f306af9a7a49.png)
Attribute PromoteでUVをPoointに移すともうグチャグチャ。

Pointは1つのPointに常に1つのため分離することが出来ません。
なのでUVをカットすることが出来ないんですね。へぇ～。
</div></details>

## Textureを逆さのままにしてる理由
中心のおじいさんの制作では入れてたUV Transformを外してあるので、Textureは反転したままになってます。
これについてはPathDeformerのForward Directionがデフォルトで+Z方向なのが理由です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/eb5ea7b0-c075-b4f7-9252-153da9cac946.png)
これは+Z方向を前方としてPathに沿うということなので、
いまおじいさんがひっくり返っても、Pathに沿ったときは上になってくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/1699e888-7145-bdfa-5dc4-ef6f99fd860b.png)
これがもし中心のおじいさんと同じ様に180度反転していたら、
逆さまになってしまいます。そんなおじいさん見たくない。

もちろんForward Directionを-Z方向にすれば反転した状態でも問題なくPathに沿ってくれます。
が、パッと見で分かりにくいところにあるパラメータを変更するのは、
他人、とくに**数カ月後の自分をワナに嵌めやすい**ため、
**なるべくデフォルト値**を保ったほうがいいかなあと思います。

## 数式があるならVEXの方が作りやすい…気がする
![Spiral.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/f18c108b-57fd-c5e4-3e91-a12b98b69e6f.gif)
おじいさん亡霊を添わせる螺旋カーブは、ある程度自由に形が作れて調整可能にしたかったので
VOPで作ることにしました。

PointのX座標とZ座標を三角関数、Y座標はptnumで値を乗算すればいけそう。
式にするとこんな感じです。

P.x = cos(radians(ptnum * frequency + offset)) * amp
P.y = ptnum * 数値
P.z = sin(radians(ptnum * frequency + offset)) * amp

これをVOPで再現するとこうなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/f56f26bb-64bc-1781-9571-d9d3ecb9ac0d.png)

VEXだとこうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/334a22db-ef29-e24d-68a4-b5e9b9c514ca.png)
VOPの方がやりやすそうだから、という理由で最初はVOPで組んでいましたが、
「式を再現するにはどういう順番で並べればいいんだっけ？」となりがちで結構苦労しました。
それに対してVEXは式そのものを書いてしまえばいいので分かりやすかったです。

もちろん慣れの問題もありますが、あれこれ組み替えて結果を試すときはVOP、
再現したい式がそもそも分かってる場合はVEXの方がいいのかなーという印象です。

# 反省点
Pathに添わせた後の、回転して時間をずらすforLoopの処理をしてますが、
すぐ重くなってしまうので、もっと他のやり方があるような気がします。
100人ぐらい出すとタイムスライダはほぼ動きません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742536/67e4a5bb-aa47-d494-24b5-538a0a9f6f7a.png)
1000体ぐらい亡霊を出せるように、この辺りも次回までの課題としたいですね。

# おわりに
元々仕事で覚えたことの復習のために、手持ちの写真素材でなにか作れないかなーと思ってたら、
いつの間にかおじいさんの亡霊を作っていました。

Houdiniはハイエンドなエフェクトやプロシージャルモデリングという印象はありますが、
こういうのも作れる（作るやつがいる）と思っていただけたら幸いです。