そんなことよりHoudiniやろうぜ!

初めての方は初めまして、そうでない方はお久しぶりです。
ここ10年龍が如くシリーズ製作にどっぷり浸かってるVFXアーティストの伊地知と申します。

今日は最近巷で大人気のHoudiniで基本部分の理解から簡単なエフェクトをUE4に表示してみるまでを皆さんにお届けしようと思います。

とりあえずこれだけは知っておきたい基礎知識
●操作方法
選択モード:s→2(Point)、3(Edge)、4(Primitive)、5(Vertex)
編集モード:Enter
カメラモード:Esc(選択モードや編集モードの時は一時的にSpace又はAlt)
ノード生成:Tab→ノード名検索キーワード(例えばattribute wrangleならaw、Sphereならsph)



Houdiniではジオメトリを扱う際に各コンポーネントの種類毎にグループとアトリビュートという情報が持てます。
データの構造と流れを各ノードに把握しておくのが重要になってきます。

コンポーネントの種類
Point、Primitive、Vertex、Detailの4種類があります。
f:id:sgtech:20180120232427p:plain
それぞれのコンポーネントにランダムで色を付けるとこの様になります。
それぞれ点、面、面毎の点、全体と覚えておくと良いでしょう

アトリビュートの種類
各コンポーネントにアトリビュートが持てます
デフォルトのアトリビュートとしてはP(座標),N(法線),uv,Cd(色)などがあります。
また独自のアトリビュートを作成して情報を格納しておくことが出来ます。
後述しますがwrangleでの記述方法としては
f@hogehoge = rand(@ptnum);
// 上記はfloat型のhogehogeというアトリビュートを作る例です。@の前の1文字で型の指定が出来ます。vならベクター型、sなら文字列型です。
// ちなみに右項は頂点番号をシードにして0~1までの乱数を生成しています。
●アトリビュートの確認方法
ビューポート上の画面下半分でAlt+] → Alt+8 と押して下さい。GeometrySpreadSheetが表示されます。
GeometrySpreadSheetはデータの構造を確認する上で重要なものなので常に表示してのが良いでしょう。
f:id:sgtech:20180120232423p:plain

最も簡単なVOPとwrangleの例:
VEXでアトリビュートを扱うにはVOP(VEX Oprater)wrangleを使った二通りの方法があります。

SphereSOPを作りPrimitiveTypeをPolygonにしてFrequencyを10に上げます。
f:id:sgtech:20180120232146p:plain

次にpointVOPSOPを作りiやダブルクリックでpointVOPの中に潜ると

f:id:sgtech:20180120232139p:plain

こんな感じのインターフェイスがあります。
左側のgeometryvopglobal1というノードはpointVOPの第1入力の事です。
そして右側のgeometryvopoutput1はこのVOPノードネットワークの結果を返します。
試しにgeometryvopglobal1の出力のP(頂点の位置)とgeometryvopoutput1の入力のCd(頂点カラー)を繋いでみましょう。
すると球に頂点カラーが設定されます。

では同じ事をwrangeでやってみましょう。

先程のsphereSOPの下にpointwrangleSOPを作成し繋げます。
f:id:sgtech:20180120232132p:plain

pointwrangleSOPのパラメータにはコードを書き込む為のテキストエリアが存在し
そこに@Cd = @P;と入力しても先程のVOPと同じ結果が得られます。
f:id:sgtech:20180120232126p:plain

この様にVOPやwrangleを用いて頂点座標や頂点カラー、法線、UVなど様々なアトリビュートにアクセス出来るのがVEXの強みです。
またwrangleの場合、非常に高速に動作する(C/C++コンパイル相当)のも魅力的です。

ちなみにこの例の場合Cd(頂点カラー)にマイナスの値が入り込んでくるので
VOPであればfit rangeVOPを用いてwrangleであればfit01関数を用いて0~1の間に合わせてやると正しいデータになります。
f:id:sgtech:20180120232119p:plain
f:id:sgtech:20180120232431p:plain

Attributeのコピーや転送
同じトポロジー同士であればAttribute Copy、距離でアトリビュートを転写するのであればAttribute Transferを使うと良いです。
また違うコンポーネントにアトリビュートを移したい時はAttributePromoteを使うのが定石です。

グループ
各コンポーネントにグループを設定出来ます。
バウンディングオブジェクトでポイントのグループを指定する例
f:id:sgtech:20180120232418p:plain
法線でプリミティブのグループを指定をする例
f:id:sgtech:20180120232414p:plain

グループのコンポーネントの変換
ポイントグループをプリミティブグループに変換するのはGroup Promoteで出来ます。

駆け足でしたがここまでで基本的なジオメトリに関する操作は理解出来たでしょう。
ここまでの知識とSOPの機能を学んでいけばプロシージャルモデリングは可能です。
他のDCCツールと比較して無い機能もあったりしますがそうした際はポータルサイトで、英語で調べるとたいていは情報を得られますので、
あまり心配しなくとも良いでしょう。



ではここからは実際にループするパーティクルを作成してUE4に出力してみましょう。

ループするパーティクルの作成

フォースフィールドの作成
まずはフォースフィールドを生み出すガイドとなるカーブを作成します。
LineとCircleからSweepに繋いでねじれたチューブを作ってCarveで螺旋を取り出すという事をやります。
その際Lineの方に@pscaleと@orientというアトリビュートを持たせてSweepに渡す事で形状の調整をします。
そしてCopyStampでY軸回転に均等コピーしておきます。
f:id:sgtech:20180120232809j:plain
point wrangleには

float div = (@ptnum)/float(@numpt);
f@pscale = chramp("widthControl",div)*chf("widthBase");
@orient = quaternion( radians(chf("roll")+div*360)*chi("twistNum")*chramp("twistPow",div),@N );
の様に記述してパラメータを出し調整する事ですぼんだ様な形状にする事が出来ます。
ちなみにアトリビュートを使わない設定にすると
f:id:sgtech:20180120232822j:plain
この様に均等なねじれになります。
あとはDOPNetworkに渡す前に@forceアトリビュートを作っておけばフォースのガイドは完成です。

ワンショットパーティクルの作成
DOPNetworkにつないでパーティクルを作成する際popnetという名前で作成しておけば
自動的にPOP ObjectPOP SourcePOP Solverを作って繋げておいてくれるので楽です。
f:id:sgtech:20180120232804j:plain

なぜループのパーティクルを作るのにワンショットを作るのかといいますと
シミュレーションでノイズをかけるとパーティクルは周期的にはなりませんので
ワンショットパーティクルを作成してそれを連続再生させてループに見せる手法を取るためです。
(残念ながらGameDevelopmentToolSetのMakeLoopはパーティクルには効きません)
f:id:sgtech:20180120232816p:plain
図にするとこんな感じです
f:id:sgtech:20180120232806p:plain
ファイルキャッシュにした時点でトライ&エラーがやりづらいのであらかじめワンショットの時点で
動きや雰囲気などを皆さんの感覚で良い感じに見えるようにしておきます。
もっとうまい方法があれば良いんですが世の中そう都合の良い話は無いですね。
DOPNetowork内に話を戻すのですが先程作ったフォースのガイドを
あらかじめDOPNetworkの2番目に繋いでおいてSOPGeometryのSOP Pathに

`opinputpath("..",1)`
としてfieldforceDOPに繋いでPOPSolverとoutputの間に差し込みます。
f:id:sgtech:20180120232930j:plain
またPOPSourceの下にちょっとしたノイズを足す為にPOP Wind DOPを足しておきます。
すると動き的にはこんな感じになります。
f:id:sgtech:20180120232919g:plain

ループパーティクルの作成
これをfile cacheSOPでキャッシュを取っておいて前述の半分にして折り返す処理をします。
Alt+Shit+Gを押してGlobal Animation Optionsを出してシーンのフレーム数を半分にして
Time Shiftでフレーム数の半分を足してMergeします
f:id:sgtech:20180120232916j:plain

すると動きがループになります。
f:id:sgtech:20180120232905g:plain

ブラーが欲しくなるので気持ち的にはここでTrailSOPを使いたくなるのですが
スタートフレームとエンドフレームで破綻するのでTrailは使わずに一旦file cacheに動きを保存しておいて
Time ShiftSOPのエクスプレッションで対応します。
f:id:sgtech:20180120232901j:plain
こうすることでループさせてもスタートとエンドがキレイにつながります。

パーティクルのメッシュ化
Particle Fluid Surfaceにつなげてパーティクルをメッシュ化します。
物凄く重いので形がカッコよくなった段階で一度file cacheに取りLoad From Diskにチェックを付け
滑らかに再生出来る状態で動きを確認します。
f:id:sgtech:20180120233044j:plain

メッシュの削減
Poly Reduceなどを用いて最適なポリゴン数にまで落とし込みます。
CleanやRemesh、Dissolveなども使っても良いかもしれません。
f:id:sgtech:20180120233019g:plain

VertexAnimationTexturesノードを使ってデータを出力する
この状態をUE4に持っていくことにします。
/outモジュールに移って Vertex Animation Texturesノードを作ります。
f:id:sgtech:20180120233014p:plain
このノード名がメニューに出てこない方は
github.com
をダウンロードして入れて下さい。
入れ方が分からない人は同梱されてるREADMEを読んで下さい。
(英語ですけどそんなに難しく無いので大体分かると思います。)
で、
f:id:sgtech:20180120233010p:plain
MethodはここではFluid、ExportNodeを設定、Target Poly Countを決定しRenderボタンを押します。
※@Cd(頂点カラー)のアトリビュートを設定しておけばColorMapのチェックボックスを付ける事で色情報も出せます。

VertexAnimationTexturesのシェーダをUE4上で構築する
次にVertexAnimationTexturesのシェーダをUE4に持っていきます。
VertexAnimationTexturesノードの下の方にあるFluid VertexAnimation UE4 Codeの+ボタンを押してUE4のシェーダーコードを表示し
f:id:sgtech:20180120233006p:plain
全選択してコピーします。
f:id:sgtech:20180120233137p:plain
UE4上で新規マテリアルを作成して
[ff:id:sgtech:20180120233132p:plain]
ダブルクリックしてマテリアルエディタを開きます。
f:id:sgtech:20180120233124p:plain
そして先程コピーしておいたUE4のシェーダーコードをペーストします。
f:id:sgtech:20180120233119p:plain
するとこの様にマテリアルエディタ上にシェーダのノードネットワークが構築されます。
f:id:sgtech:20180120233115p:plain
マテリアルエディタの詳細タブの目玉マークのプルダウンメニューからアドバンスな詳細を表示にチェックを付けます。
f:id:sgtech:20180120233308p:plain
さらにカスタムUVの数3に設定します。
あとはノードネットワークのコメントに従って対応するパラメータを接続します。
f:id:sgtech:20180120233303p:plain
これでマテリアルは完成です。

マテリアルインスタンスの設定
先程Renderボタンで作成されたFBX(モデル)とEXR(テクスチャ)をUE4にドラッグ&ドロップしてインポートします。
f:id:sgtech:20180120233259p:plain
「全てインポート」で構いません。
f:id:sgtech:20180120233251p:plain
次にマテリアルインスタンスを作ります。
f:id:sgtech:20180120233248p:plain
ダブルクリックして設定ウィンドウを開き先程作ったマテリアルを親マテリアルにします。
f:id:sgtech:20180120233420p:plain
HoudiniのVertex AnimationノードのBBOX MAXとMINの値をコピーして
UE4にペーストします。あと該当するチェックやフレーム数も同様です。
f:id:sgtech:20180120233417p:plain
あとポジションのテクスチャも設定しておきます。
f:id:sgtech:20180120233412p:plain
これでマテリアルインスタンスの設定は出来ました。

モデルにマテリアルインスタンスをアサインする
先程インポートしたFBXモデルをダブルクリックして設定ウィンドウを開きます。
マテリアルスロットに作成したマテリアルインスタンスを設定します。
ビルド設定の「最大制度のUVを使用」にチェックを付けてモデルへのマテリアルインスタンスの設定は終了です。
f:id:sgtech:20180120233409p:plain

これでモデルをビューポートにドラッグ&ドロップすればUE4上で再生出来るループする流体エフェクトの完成です。

f:id:sgtech:20180120233345g:plain

いかがでしたでしょうか?
ゲームに出力する部分は意外と手続き的な処理が多く煩わしさはありますが、Houdiniで作った流体表現が
ゲームに表示出来るというのは感慨深いものがあるのではないでしょうか?
こういったエフェクトの手法は日々進化していきます。
現状ビルボードが主流のゲームエフェクトですがデータとシェーダを工夫する事でこの様な表現が可能になりました。
5年後10年後どういった表現が可能になるのかワクワクしますね。

という訳で恒例の求人タイムです。
弊社ではHoudiniに興味を持って取り組めるような人を募集しています!
私の作ったシーンを見放題にもなれますし社内でハンズオンセミナーなども開催していますので
興味のある方は以下のリンクをクリックしてみてください。



採用情報 | セガ企業情報サイト

Powered by はてなブログ