Houdiniでドット絵作成

#はじめに
Houdiniでドット絵を作る方法を書いた
使用ツールは**Houdini Apprentice 18.5.351**

画像生成、コンポジット・・・**_COP2_**
レイヤー等編集・・・**_SOP_**
タスク管理・gif作成・・・**_TOP_**


#1.要点
Houdiniでドット絵を作る上で比較的**重要**な点を述べる

##リファレンス画像
リファレンス画像は**Fileノード**で読み込める
![bandicam 2020-11-11 22-14-48-063.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/46ce07d4-d5f8-c8b8-a09e-faa3835be799.jpeg)

下のgifはリファレンス画像を見ながら**Group Paintノード**を使って星の形に**gridをグループ化**しているところである
**シーンビュー**ではgridの**f@Alpha**アトリビュートを**０にすると透明**、**１にすると不透明**になるので**見やすい値**に変えると良い
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/aed67b98-f6ee-04f7-2782-75444c2e2e31.gif)
<font color="DarkGoldenRod">- _Alphaを変えながら**Group Paintノード**でグループ化_</font>

##画像の生成
**VOP COP2 Generatorノード**で解像度を設定
![bandicam 2020-11-11 22-01-20-578.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/e7a4ebff-9d2c-a17c-8456-af29a2f170c4.jpeg)
![bandicam 2020-11-11 22-04-53-928.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/774040ab-213a-7f67-9846-21fac738b82f.jpeg)
<font color="DarkGoldenRod">- _32x32ピクセルに設定された画像_</font>

#COPの画像をSOPへ
SOP内に**COP2 Networkノード**を作ると画像を**Volume**や**Mesh**として持ち込める
![bandicam 2020-11-11 23-23-26-203.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/19d62779-c2d1-e7f6-a560-ef7f5a8d1fe8.jpeg)
![bandicam 2020-11-11 23-25-03-534.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/8197af78-55aa-9a11-cfd9-6c65d38a31b6.jpeg)

**Mesh**は**一つのピクセル**が**一つのポイント**として表現されている
この記事では**Mesh**の状態のものを編集する


##ペイント
**COP2 Networkノード**で作られた**Mesh**は**色v@Cd**と**不透明度f@Alpha**の**ポイントアトリビュート**を持っている
SOPでこれらの**アトリビュートを変更**していく

####方法
- **v@Cd**を変更すると**色が変えられる**
- **透明**にしたい部分は**f@Alphaを0.0**にする
- **不透明**部分は**1.0**にする

**Attribute Paintノード**で直接Cdを変更する手もあるが、**後から色を変更**したくなった場
合などでもすぐ対応できるよう、先に着色する場所を**Group Paintノード**等で**グループを設定**すると良いだろう

**Colorノード**を使えば指定したグループを**一気に**染められる

---
###カーブ・ストロークによるペイント

####方法
1. Meshはあらかじめ**f@Alfha**を**0.0**に設定しておく
2. **Draw Curveノード**等で自由に**ポリゴンカーブ**を作る
3. カーブは**v@Cd**を編集、色を付けて**f@Alpha**を**1.0**にする
4. Meshにカーブから**v@Cd**と**f@Alpha**を**Attribute Transferノード**で転送するとペイントされている!

![bandicam 2020-11-26 00-25-15-343.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/2d53e281-1525-5d32-bbd1-20bac4fd8330.jpeg)
<font color="DarkGoldenRod">- _自由に作ったカーブ_</font>

![bandicam 2020-11-26 21-46-16-687.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/e3f42420-6390-7e0a-551b-218e7a29b16b.jpeg)
<font color="DarkGoldenRod">- _Meshのポイントアトリビュートv@Cdの編集_</font>

---
###ピクセルパーフェクトな線
ピクセルパーフェクトな線をある程度Houdiniで再現することが出来たので紹介する
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/4ccbe627-d987-0c83-9049-f353f6ea7d40.gif)
<font color="DarkGoldenRod">- _実際にHoudiniで描いた様子_</font>

![bandicam 2020-11-27 16-04-39-997.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/d72d15dc-5892-a8c6-8ddf-82dd88b6450d.jpeg)
<font color="DarkGoldenRod">- _主要なノード_</font>

[pixel_perfect.hipnc](http://www.mediafire.com/file/p3jqxls5kt70561/pixel_perfect.hipnc/file)

---
###任意のジオメトリからMesh（レイヤー）へ色を転送

####方法
1. 好きなジオメトリを**用意**する
2. 下の画像の様にMeshと１のジオメトリを**並べる**
3. Meshのポイントに**ベクトルを設定**する
4. [**Rayノード**](https://www.sidefx.com/docs/houdini18.5/nodes/sop/ray.html)を使って色（v@Cdやf@Alpha）を移す

- 法線等のベクトルをポイントに持たせると**Rayノード**を使ってベクトルの方向にあるv@Cd等の**アトリビュートを取得**できる
- **Rayノード**で**Create Point Groupにチェック**を入れると色が移せたポイントを**グループ化**してくれる

※このグループは**アウトラインの作成**にも使える

![bandicam 2020-11-27 12-59-48-623.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/59d89e92-269a-c1c9-8264-bc0736489b95.jpeg)
<font color="DarkGoldenRod">- _Before front_</font>

![bandicam 2020-11-21 13-47-13-209.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/99ee8c36-817d-5fb8-476b-085634c7a0f7.jpeg)
<font color="DarkGoldenRod">- _Before perspective_</font>

![bandicam 2020-11-21 13-49-53-567.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/b7377211-6aae-97a4-8848-0f7df02e386e.jpeg)
<font color="DarkGoldenRod">- _After perspective_</font>



---
###アウトライン
![bandicam 2020-11-26 22-20-09-283.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/7e038aac-b9a2-2a21-579e-4b2802607f23.jpeg)

####方法

1. アウトラインを付けたいMeshの**ポイントグループ**を**GroupExpandノード**で**広げる**
- **GroupCombineノード**で元のグループを**引く**
- グループの**外側にグループ**ができるのでそこを**Colorノード等で着色**する

![bandicam 2020-11-26 22-19-55-299.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/84c8d351-f82c-92c0-31ba-02ec97c9b67c.jpeg)
![bandicam 2020-11-26 22-19-41-222.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/582b78aa-cfad-1282-5a07-3bc18972de02.jpeg)
<font color="DarkGoldenRod">- _グループのブーリアン_</font>

---
###グラデーション
![bandicam 2020-11-26 22-26-25-192.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/2b37f7bd-182d-0aee-88cf-747ee959d990.jpeg)

####方法
1. グラデーションさせたい場所にカーブを引く
- **Resampleノード**で**f@curveu**を作る
- [**Rayノード**](https://www.sidefx.com/docs/houdini18.5/nodes/sop/ray.html)で**f@curveu**アトリビュートをラインから取ってくる
- **f@curveu**を使って**Colorノード**の**Attribute Ramp**で**色**を付ける

![bandicam 2020-11-30 21-27-29-734.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/acd37cdd-e2d5-6b92-b9de-c159e433bd53.jpeg)

![bandicam 2020-11-26 21-56-55-292.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/53fb363d-d8b2-d2f8-02b6-8d9846b2aaae.jpeg)
<font color="DarkGoldenRod">- _Curve U Attribute_</font>

![bandicam 2020-11-30 21-34-42-503.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/2c850089-7bae-7f09-3a9a-73085d4ba12b.jpeg)
<font color="DarkGoldenRod">- _Rayノードパラメータ_</font>

![bandicam 2020-11-30 21-27-53-029.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/f19f4fec-df0a-53c4-bc33-b3c1473410fb.jpeg)
<font color="DarkGoldenRod">- _Rampによる着色_</font>

---

###Game Boyの色を使う
![bandicam 2020-11-29 21-59-30-243.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/66f26ab4-0319-c559-5bcd-caa9de610b3a.jpeg)
HoudiniではないがAsepriteには良いプリセットがたくさんある
試しにGame Boyのプリセットを画像としてHoudiniに持っていく

Asepriteから**png**でExportし、Houdiniの[**Color Editor**](https://www.sidefx.com/docs/houdini/ref/windows/coloreditor.html)で読み込む
下の画像の赤枠をクリックすると**画像ピッカー**が表示される
![bandicam 2020-11-29 22-28-00-271.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/cd2b4dff-0f39-221b-8504-c75ddc924023.jpeg)

画像をクリックするだけで簡単に**色を抽出**できる

念のため色をHoudiniで確認してみる
![bandicam 2020-11-29 22-35-55-181.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/55c5b2bb-b619-74cd-eacc-6c4775d44f48.jpeg)
<font color="DarkGoldenRod">- _AsepriteのRGB_</font>

![bandicam 2020-11-29 22-37-05-761.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/651aac3e-1b58-d560-8b01-6a4a588a36f6.jpeg)
<font color="DarkGoldenRod">- _Houdiniで２５５を掛けたRGB_</font>

色の一つはきちんと**（RGB　１５５　１８８　１５）**になっており、**寸分の狂いなく抽出**出来ている

---

##シーンビューでもう少し見やすく

Meshの持っているv@Cdやf@Alphaは**ポイントアトリビュート**だ
その為シーンビューの映像と最終的に出力される画像には**ギャップ**がある
![bandicam 2020-11-21 12-02-38-647.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/e37abee9-e3e3-d5a6-a9b4-487c601ee04b.jpeg)
<font color="DarkGoldenRod">- _シーンビューの映像_</font>

####改善方法

1. **Resampleノード**でDistance Attributeを**pscale**として作成
2. Meshの下に接続する
3. 一辺が**１**の**grid**を作る
4. 2と3を**Copy to Pointノード**につなぐ


![bandicam 2020-11-21 12-12-47-168.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/a6e9648d-4b83-d0d6-c1ce-26828e902bff.jpeg)

![bandicam 2020-11-21 12-12-58-150.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/0c8e1ffc-e4f0-9121-a6f6-01d16c26e6f9.jpeg)
<font color="DarkGoldenRod">- _Distance Attribute_</font>

![bandicam 2020-11-21 12-13-13-353.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/7fbbcc11-0a9d-a298-eae8-3d717b2f1fb1.jpeg)
<font color="DarkGoldenRod">- _出力画像に近くなった_</font>

ライトの**Specular**や**Emission**を切っておくとなお良い
![bandicam 2020-11-26 00-09-56-051.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/fb536a86-7eab-416e-19d3-89ffeb4fdc95.jpeg)
<font color="DarkGoldenRod">- _シーンビューのライト_</font>

##フレーム毎のバリエーション
バリエーションを作りたい部分をたくさん**コピー**して**変更・マージ・必要なフレームの取り出し**をする

下の画像ではフレーム毎に**Editノード**を使ってバリエーションを付けている
またそれぞれの**フレームを判別**するための識別子を**Attribute Expressionノード**で作っている
![bandicam 2020-11-21 11-26-48-360.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/30a8f44e-e029-fe9b-cb0b-7e0eef58ff5b.jpeg)
<font color="DarkGoldenRod">- _フレーム毎に変化をつける_</font>


[Object Mergeノード](https://www.sidefx.com/ja/docs/houdini/nodes/sop/object_merge.html)でワイルドカードを使って**一気にマージ**すると楽である
たくさんのバリエーションを作っていても**NULLノード**の**名前**さえ合っていればマージしてくれる
![bandicam 2020-11-21 11-31-41-133.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/283c58ae-71ae-05ac-0ed9-f688155377f2.jpeg)
<font color="DarkGoldenRod">- _マージされたバリエーションたち_</font>

**Blastノード**を使うと**フレームの識別子**からフレームを取り出せる
![bandicam 2020-11-21 11-39-25-434.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/c450bcc3-c776-080c-2269-2289759bc5cb.jpeg)
<font color="DarkGoldenRod">- _i@frameというアトリビュートを基にフレームを取り出す_</font>


##SOPのレイヤー（Mesh）をCOPへ
SOPからCOPへの画像の移動は以下のツイートを参考にした
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">要望があったので、hipファイルアップしました。<br>サブネットにまとめてるので、中身見るなり、HDAにするなり自由に使って下さい。<a href="https://t.co/YVEQ6ptx7U">https://t.co/YVEQ6ptx7U</a></p>&mdash; 大翔士 (@d658t) <a href="https://twitter.com/d658t/status/1159444296421933056?ref_src=twsrc%5Etfw">August 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

####方法
1. 事前にSOP内のMesh（レイヤー）をX,Y座標共に０から１の範囲に**ピッタリ**合うように大きさを変えておく
2. COP内の**VOP COP2 Generator**や**VOP COP2 Filterノード**で**VOPを組む**事でSOP内の**v@Cd**や**f@Alpha**を画像の**R,G,B,A**として**拾ってくる**事が出来る

※1は縦・横の比率が変わって問題ない
大きさをピッタリ変えるには**Mach Sizeノード**が便利だ
![bandicam 2020-11-28 22-02-11-851.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/53f3fb2a-3092-7beb-08a5-979ef6a121b3.jpeg)
<font color="DarkGoldenRod">- _**Mach Sizeノード**のパラメータ_</font>


![bandicam 2020-11-21 11-53-00-715.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/48ac0ae2-d8de-6b14-47f1-db9a2a6dbb2e.jpeg)
<font color="DarkGoldenRod">- _**VOP COP2 Filterノード**による画像の取得_</font>
**VOP COP2 Generator**や**VOP COP2 Filterノード**は入力のワイヤーを繋ぐと上流ノードの解像度を引き継ぐ事が出来る
※解像度を入力する手間が省ける

![bandicam 2020-11-26 00-41-39-905.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/d2958420-fa01-ec22-7581-1bc911f78983.jpeg)
<font color="DarkGoldenRod">- _VOPによるR,G,B,Aの設定_</font>

##コンポジット
**VOP COP2 Generator**や**VOP COP2 Filterノード**で得られた画像を**合成**していく
最後に**ROP File Outputノード**で画像を**出力**している
![bandicam 2020-11-21 12-25-24-150.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/26bd8341-2bb9-66c9-dbb4-c6a293368a9e.jpeg)

![bandicam 2020-11-28 21-20-20-035.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/a6f066cd-f737-a3be-30d2-f577141c82f5.jpeg)

##画像の拡大
ドット絵はそのままだとピクセル数が少なく画像としては**小さい**
ピクセル数を増やして**大きく**したい場合がある

**Scaleノード**を使うと**解像度（大きさ）**を変更できる
![bandicam 2020-11-28 20-52-20-326.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/8a92350f-f672-992f-57df-a021c9e75db4.jpeg)
<font color="DarkGoldenRod">- _Scaleノード_</font>

下の画像では**Scaleノード**で縦と横のスケールを**１０倍**にしている
また、Upscale Filterを**Point**にするとピクセルの形を**クッキリ綺麗**に保ってくれるのでドット絵的にはよろしいと思う
![bandicam 2020-11-28 20-53-07-272.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/9d385a03-2b5b-82ec-95ff-f30e757b5862.jpeg)
<font color="DarkGoldenRod">- _Scaleノードのパラメータ_</font>

![bandicam 2020-11-28 21-03-28-004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/d0f3eae0-ea48-e9d7-8af3-381090fa1ca6.jpeg)
<font color="DarkGoldenRod">- _大きくなってもクッキリ綺麗な画像_</font>

##タスク管理
タスク管理を行わない場合、SOPの計算の前にコンポジットが行われる等**意図しない動作**も起こり得るようだ
一度全てのレイヤー（Mesh）を外部に書き出してそれをもとにコンポジットする必要がある
![bandicam 2020-11-21 12-56-41-997.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/ab356820-be3b-ad0c-094c-b612bdbf10e8.jpeg)
<font color="DarkGoldenRod">- _レイヤーの書き出し_</font>

![bandicam 2020-11-21 12-58-52-921.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/4450c578-6c30-25e1-fae9-7f379874a543.jpeg)
<font color="DarkGoldenRod">- _１フレーム毎にコンポジット_</font>


##gif化
**FFmpeg**をインストール・Pathを通すとTOP内で**FFmpeg Encode Videoノード**が使えるようになる
![bandicam 2020-11-21 12-59-17-606.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/0364c38c-0468-c8c6-3877-848079c8737d.jpeg)

**FFmpeg Encode Videoノード**の設定

- File Tagは上流ノードでコンポジットした画像のタグを**file/image**にしていたので**file/image**と書く
- Output File Pathで出力するファイル名を****.gifにする
- Frame Per SecondとFormatにチェックを付ける
- 大きさを変更したい場合にはSizeの値を変える

![bandicam 2020-11-21 12-40-32-496.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/99b09c87-a014-9c3f-89c4-c14226debf71.jpeg)

[FFmpeg公式ドキュメント](https://ffmpeg.org/documentation.html)

#2.作例紹介
下のgifは実際にHoudiniで作ってみたもの
![Dot_Picture.2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/3b85426b-ede6-2f7f-51cb-cebf4bf3bafe.gif)
<font color="DarkGoldenRod">- _星と丸い何かが動くgif_</font>

全体のノードの構成は下のようになっている
![bandicam 2020-11-13 22-21-39-230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308102/6b256009-0e7e-6967-0a32-0c40a87def98.jpeg)

###各ノードの内容

- **cop2net1**

　画像の生成・レイヤーの合成を行う処理

- **reference_picture**

　リファレンス用画像

- **grid**

　Meshの状態の何も書かれていない画像
　サイズをリファレンス画像の大きさに近づけてある
　全てのレイヤーの基本になる

- **library**

　何度も行う処理はここにまとめておいた

- **Layers**

　レイヤー別にMeshが置いてある

- **topnet1**

　１．各レイヤー・フレームのキャッシュをとる
　２．レイヤーの合成
　３．画像の出力
　４．gif化
　この４つを順番に実行させる処理

[Dot_Picture.hipnc](http://www.mediafire.com/file/uw6wxv1unnv8ubo/Dot_Picture.hipnc/file)


#3.今後の課題
カラーパレットの効率的な準備
フレーム毎に持続時間を変える
等