Unityエフェクトレシピ 02 - 六角形シールド表現 (1/2)
はじめに
六角形シールド表現を作ってみました。
本記事では、このエフェクトの作り方を紹介したいと思います。
記事が長くなりそうなので、今回は3Dモデルの作り方のみ紹介します。
シェーダーの作り方は改めて別の記事で紹介しようと思います。
今回のエフェクトやhiplcはGitHubにて公開中です。
後編はこちら
Unityエフェクトレシピ02 - 六角形シールド表現 (2/2) - rn.log
環境
Windows 10
Unity 2020.1.0b2
Houdini 18.0.460 (Indie)
第1章. 3Dモデルの作成
Houdiniを利用して、五角形や六角形を球面上にしき詰めた3Dモデルを作成します。
モデル頂点には以下のデータを持たせています。
アトリビュート | 説明 |
---|---|
uv |
テクスチャ座標(モデル全体)
|
uv2 |
面それぞれに対して展開したテクスチャ座標
|
頂点カラー(Rチャンネル) |
メッシュの中心から外側へ向かう、0~1のグラデーション
|
頂点カラー(Gチャンネル) |
五角形・六角形の番号(0, 1, 2, ・・・, N)をNで割り、0~1の範囲に収まるようにしたもの
|
※ 作成したモデルデータを最終的にFBXファイルとして出力しているため、Houdini Indieライセンス以上が必要になります。
3Dモデルの作り方 解説
STEP 1 : Sphere
Sphereノードを作成し、Primitive Type = Polygonに設定します。
STEP 2 : Divide
Divideノードを接続し、Compute Dualのチェックを入れます。
六角形と五角形を敷き詰めたような形状になります。
STEP 3 : Subnetwork
Subnetworkの実行結果は以下のようになっています。
Subnetworkの中身はこのようになっています。順番に解説していきます。
STEP 4 : Color
Colorノードを利用し、頂点カラーを{0, 0, 0}に設定します。
STEP 5 : AttributeWrangle
プリミティブ番号(@primnum)が0 ~ 1の範囲に収まるように @numprim - 1 で割り、
結果の値は @id アトリビュートとして保存しておきます。
f@id = (float)@primnum / (@numprim - 1);
※@primnumはint型なので、float型にキャストしてから割っています。
※@idの代わりにf@idと書くことで、@idはfloat型であることを明示することができます。
STEP 6 : For-Each Primitive
For-Each Primitiveでは各メッシュにグラデーションをつけています。
さらに細かく見ていきます。
For-Eachループの開始部分を見ると、六角形(or 五角形)になっています。
STEP 6.1 : PolyExtrude
Poly ExtrudeノードのInsetを利用して、多角形を内側へ押し出します。
また、Front Groupのチェックを入れます。
これにより、押し出したプリミティブに対してextrudeFrontというグループが割り当てられます。
STEP 6.2 : Group Promote
押し出したポイントを一つにまとめる、という操作を下流で行いたいので、
extrudeFrontグループをPrimitiveからPointへ変換します。
STEP 6.3 : Fuse
Fuseノードでポイントを一つにまとめます。
グループにextrudeFrontを設定することで、先ほど押し出したポイントのみをまとめることができます。
STEP 6.4
ColorノードでグループextrudeFrontに対して赤色(1, 0, 0)を割り当てます。
内側から外側へ向かうグラデーションを作ることができました。
ForEach Endノードを見ると、すべての多角形にグラデーションが適用されていることが確認できます。
STEP 7 : UV Texture
下流のUV Textureでは、モデル全体にuvを割り当てています。
ちなみに、UV Quick Shadeを使うとUVをプレビュー表示することができます。
STEP 8 : Attribute Wrangle
v@Cd.g = prim(geoself(), "id", @primnum);
※ここでは、primitiveコンポーネントとして保存されている@idアトリビュート(0~1の値)をとってきて、@Cdアトリビュートのgチャンネルへ代入しています。
※v@Cdと書くことで、@Cdアトリビュートはvector型であることを明示しています。
STEP 9 : UV展開(uv2)
五角形、六角形それぞれに対し、個別にテクスチャ座標を設定します。
uvはモデル全体のテクスチャ座標としてすでに利用されているため、
代わりにuv2へ設定します。
UV Viewモードでuv2を確認すると、UVが0-1の範囲に収まっていません。
今回これは都合が悪いので、uv2が0-1の範囲に収まるように修正を加えていきます。
STEP 9.1 : uv2の最小値の取得
Attribute Promoteでuv2の最小値をuv_min(detail)として保存します。
STEP 9.2 : uv2の最大値の取得
Attribute Promoteノードでuv2の最大値をuv_max(detail)として保存します。
STEP 9.3 : uv2の範囲変換
AttributeWrangleを利用して、uv2の範囲[uv_min, uv_max] を [0, 1]へ変換します。
// detailが持つアトリビュート uv_min を取得 vector uv_min = detail(geoself(), "uv_min", 0); // detailが持つアトリビュート uv_max を取得 vector uv_max = detail(geoself(), "uv_max", 0); // uv2 を 範囲(uv_min ~ uv_max)から 範囲(0 ~ 1)へ変換 v@uv2 = fit(v@uv2, uv_min, uv_max, 0, 1);
UV View モードを見ると、UVが0~1の正方形に収まっていることが確認できます。
以上でSubnetworkの解説は終わりです。
STEP 10 : ROP FBX Output
最後はFBXファイルとして出力するだけですが、今回は便利なTipsを一つご紹介したいと思います。
OUTPUT Fileを以下のように設定すると、入力ノードと同名のFBXを$HIP階層へ出力することができます。
`strcat($HIP, strcat(opinput(".", 0), ".fbx"))`
opinput(".", 0)は1番目の入力ノード名を取得するようなエクスプレッションです。
今回はROP FBX Outputへ SK_fx_hex_sphere01というノードが接続されているので、
SK_fx_hex_sphere01.fbxファイルが出力されます。
以上でモデルデータの作成は完了です。