【Houdini】氷柱用のモデルを作る
Houdiniのモデリングの記事です。
UE4に入れてマテリアルを設定したら、こんな感じになります
結構綺麗かなと、この角度になっているのは、ライディングの影響が解りやすい角度を探した結果です。
全体の構図
大体の役割としてはコメント参照にて
流れとしては、6角錐を合わせたような図形を作ります。
この時点でUV展開をして、まず細長くし、それを基本の形とします。
それを、複製して、角度を外向きに変更します。
これと、中心のを合成させて、その後ポリゴンを、割ったり位置を変えたりで形を整えます、最後に仕上げて下を切り取ります。
中心の基本となる部分
この部分はすぐできそうな形ですが。
基本形状となる、六角錐を合わせたような形は、Sphereで作ります
Polygon Meshに変更して、あとはポイント数などを調整します。
続いて、UVTextureでUV展開します、設定は初期設定です。
その次に、uvquickshadeを繋ぎます、これでUV座標が表示されると思います。
次にPointWrangle
if(@P.y == 0){@P.y += ch("Height");}
コードはこちらを
その後、赤枠の部分をクリックすると、赤線の部分が出てくるので自由に動かしてください、大体0.45位が良いかなと。
コードの内容としては、IF文でY軸が0のポイントを判定して
そのポイントのY軸を、このスライダーの数値分加算しています。
Y軸が0になるのは、周りの部分のみなので、この部分のみ座標を変化させます。
続いてTransformノード
こちらは、外からパラメータを弄れるようにしてあります、線の色が同じ部分は同じパラメータです。
このパラメータの参照箇所としては色々ありますが、後から調整しやすくする為に、SubNetworkノードに纏めています。
SubNetworkノードは、ノードの中にノードを入れることができ、このノードツリーも全てSubNetworkの中に入っています。
ここから、パラメータを追加することができます、ドラッグ&ドロップで右側に移します。
ここで、パラメータの下限と上限を設定できます、ただしこの上限などは、スライダーでどこまで変化できるかで、数値を直接入れる場合には特に影響ありません。
今回のパラメータの全体図はこちらに、Floatと、Float2とInt型を使っています。
パラメータの部分を右クリックから、コピーして
貼り付けたいところでは、右クリックからこれで貼り付けます。
なお、この部分の数値は基本的に直接指定しても問題は特にないです、あとで作り変えたいときなどは、作っておくと便利になります。
途中でパラメータの説明入りましたが、ここで中心の元は完了
周りの氷柱
次はこの部分です
左上のTransFormと、PointWrangleから
基本サイズを調整する用です。
if(@P.y == 0){@P.y -= ch("Height");}
コードはこちら
中心の位置をずらす処理、中央のにもあるのと同じパターンです、ただこちらは逆さま向きです、理由は、コピーした時に、向きが変になった対処、理由はちょっと解ってないです。
右上側の、SphereとPointWrangle
コピーするためのポイントの元になるジオメトリです
文字列の部分は、ポイント数です、ここを弄れるようにすれば、周りの氷柱の数を調整できるようになります。
if(@P.y != 0){removepoint(0,@ptnum);}
@P *= `chs("../IceLocal")`*(1+(rand(@ptnum+`chs("../Randseed")`)*`chs("../LocalRandLevel")`));
コードはコチラ
if(@P.y != 0){removepoint(0,@ptnum);}
ここの部分は、ポイントのYが0でないポイントを全て削除します
@P *= `chs("../IceLocal")`*(1+(rand(@ptnum+`chs("../Randseed")`)*`chs("../LocalRandLevel")`));
ここは、発生位置にランダム性を持たせるためです。
次の、CopyToPoint、PointWrangle、Unpack
この次に、行列などで回転させたりするので、このチェックでPack化します。
@P += set(0,`chs("../IceHeighty")`,0);
vector4 @quat = {0,0,0,0};//クォタニオン生成
vector scl = set(0.5*(1+(rand(@ptnum+`chs("../Randseed")`)*`chs("../SizeRandLevel")`))/2,2,0.5*(1+(rand(@ptnum+`chs("../Randseed")`)*`chs("../SizeRandLevel")`))/2);
matrix3 m = ident();
vector4 q = quaternion(radians(`chs("../IceRotation")`),{1,0,0});
vector4 q2 = quaternion(atan2(@P.x,@P.z),{0,1,0});
vector4 q3 = qmultiply(q2,q);
vector4 q4 = quaternion(radians(rand(@ptnum)*360),{0,1,0});
vector4 q5 = qmultiply(q3,q4);
scale(m,scl);
m *= qconvert(q5);
setprimintrinsic(0,"transform",@ptnum,m,"set");
結構長いです...
最初の行は、全体の高さを変えるだけです
それ以降は、クォタニオンやら行列関係使ってます
最初に、X軸を傾けて、その後Atan2で角度を習得してその角度でY軸に回転させます。
そうすると、外側に向くようになります。
作ってから期間空いて内容忘れてる部分もあるので、コピペなどしてご利用下さい...
最後にUnpackで、Packを解除します
合成、仕上げ
ノードは上からMerge、Subdivide、Pointwrangle、Subdivide、Clip
Mergeは、中心のと外側のを合成します。
Subdivide
ポリゴンの分割数だけを増やします。
PointWrangle
@P.x += (rand(@ptnum)-0.5)*(`chs("../SizeRandLevel")`)*0.1;
@P.y += (rand(@ptnum+1)-0.5)*(`chs("../SizeRandLevel")`)*0.1;
@P.z += (rand(@ptnum+2)-0.5)*(`chs("../SizeRandLevel")`)*0.1;
コードはこちら、X,Y,Z軸を、それぞれバラバラに位置を移動させます、これにより、全体を変形させます。
Subdivide
ここで更に分割します、Crease Weightのパラメータで、分割した部分を調整する事ができます、ここも外部から操作できるようにするのも良いかなとは。
最後にClipを繋げば完成です。
外部のパラメータ参照が多くて結構わけわからなくなってきそうなので、一応データ置いておきます。
ちょっと雑な説明になってそうですが、次から記事書く事考えてファイルも作っていけたらなと思います。