HoudiniでWangTileSopsを使おう。

#はじめに
###概要
WangTile系のLabsが追加されていたので、Wang's Tileノードを使用方法＆備忘録。
登場したてのノードなので、公式文章等が無く個人の使用感を基に書いているため所々間違っている可能性があるので、不明点等ありましたら指摘いただければ幸いです。

公式紹介
WFC Dungeon Generator 
https://www.sidefx.com/tutorials/wfc-dungeon-generator/
↑HDAもDL出来るので確認してみてほしい。

###使用環境
Houdini 18.0.460
WFCノード群は18.0.423(2020/4/10 更新分)でSideFX Labsに追加されたので、使用する場合は更新する必要があるかもしれません。
#Wang's Tileとは
##参考サイト
*ノードの説明が早く見たい方は飛ばしてください*
https://en.wikipedia.org/wiki/Wang_tile
↑WangTile[Wikipedia]
1961年に数学者Hao Wangによって提唱された非周期タイルの充填システムのことです。ゲームではテクスチャのリピート感をなくすのに使われている（らしい？）
http://www.cr31.co.uk/stagecast/wang/intro.html
↑このサイトが参照されることが多い。

http://ikatnek.blogspot.com/2020/06/wfc.html
↑実際の使用例。日本語で情報がまとめられている。

##アルゴリズムを読み解く
Wang Tileは大きくエッジ評価とコーナー評価の2種類があります。
エッジ評価とは、上下左右のタイルをサンプリングして評価を決めるという手法です。アウトプットされる結果は全体的に斜めのレイアウトになります。
コーナー評価とは、右上・右下・左上・左下の4か所で評価を決める手法です。こちらは全体的に縦横のグリッド形式になります。
Houdiniで使用されている評価方法はこの2つを複合したブロブ評価というものです。(上から時計周りで2進数を使うことで評価値を決めている。)
http://www.cr31.co.uk/stagecast/wang/blob.html
さて問題です。中心の3つを単純にエッジ・コーナーで合わせた評価するとどうでしょう？
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/64acfe01-38c6-de57-1d9f-c87eadefb04f.png)
正解はこれです。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/6f98e889-621a-2a44-8065-6bb9280fd0ae.png)

青で示したように同じ形状の壁を生成したいのに評価値が違うのは扱いにくいですね。
なのでブロブ評価ではこういう評価のされ方がされています。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/b6d48d48-d4c9-66d5-5ee8-690a09a58793.png)
これで同一形状に対して1つの数値に落とし込むことができました。
このようにグリッドに対して番号を振り与えていくのがWangTileSopsの正体です。



#ノード説明
SideFX Labsに現在追加されているノードは2種類。すべてSOPです。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/25bbf5ff-889c-de37-7f8a-6b038040e5f0.png)


**wang_tiles_sample**
**wang_tiles_decoder**
これらの紹介から。

##wang_tiles_sample
WangTileで使われるタイルのサンプルが用意されています。
ここで重要になるのがPrimitive Attributeに設定されているnameです。
nameに1つ前に説明した番号が割り振られています。
このnameの仕組みに従って別のアセットを用意すればこれを無理に使う必要はないです。

| 項目      | 説明       |
|:-----------------|:-----------------|
| Vertex Color       | 用意されている部屋パーツごとに別の色をPointAttributeに与える       |
| Align and Distribute       | 用意されているパーツの一覧になる     |

<details><summary>さらに深堀り</summary>ノードを展開すると構成はこのようになっている。![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/e4ba4e80-ed80-8135-1615-700095b3c37d.png)
特に複雑なことはしていないですね。stashSOPで保存されているのがすべてです。SideFX Labsのalign and distributeは便利だがname Attributeが消えてしまうので、中身を解析するときはAttribute Copy(name)等を使うと復元できるのでそこから読み解くとよい気がしている。</details>

##wang_tiles_decoder
Cd PointAttributeを保持したGridPointsを入力してWangTileの数値評価の値をname PointAttributeに設定する処理を行うノード。

| 項目      | 説明       |
|:----------------|:-----------------|
| 1st INPUT       | GridPointを入力(PointAttributeにCd情報が必要) |
|||
| Mode | WangTileの評価の方法の種類。|
| Sample Channel|評価する色を選択する。 |
| Rows|INPUTに入力したポイントの横のポイント数を入力する |
| Columns| INPUTに入力したポイントの縦のポイント数を入力する|
| Keep Color| INPUTのポイントのカラーを引き継ぐ。|
Modeは今のところBlob Tilesetしかないが、今後Edge TilesetとかCorner Tilesetとか出ると色々面白いことが出来るだろう。
Sample ChannelはCd[r],Cd[g],Cd[b]のどれを参照するかということです。重要なのがCdの値が0以上0.5未満と0.5以上1以下の2種類に分けて使用されます。単純作業をしたい場合は0,1で行うといいでしょう。
RowsとColumnsは手動で入力します。**ポイントナンバーの0→1→2の方向がRows、それと逆がColumns!!**
**Grid/wfc_initializeを生成するときとRows/Columnsが逆なので要注意。**
<details><summary>さらに深堀り</summary>ノードを展開すると構成はこのようになっている。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/91eb36bc-36f6-7148-419e-c343d58b29fe.png)
pointwrangleオンリーで大体終わっているので特に説明することはないきがする。やっていることは**Wang's Tileとは**を読んでください。
</details>
#作例
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613929/98a6e798-23a6-8ef2-52be-8b4bc516ee86.png)
fuse SOPとpolydoctor SOP(Clean SOP)を組み合わせると綺麗な面が出来ます。よくやるパターンですね。

#おわりに
WFC Sopsと組み合わせるとめちゃくちゃ便利なWangTiles SOP（デザイナーズコンボだと思っている。）
WFCのサブウエポン的な感じになってますが勉強の一助になれば幸いです。
それでは、しゃーした～。