※この記事ではHoudini 17.0.416 Apprenticeバージョンを使用しています。
※Houdiniの基本的な操作やウィンドウの役割等は他のチュートリアルで既に分かっている前提です。
この記事の目的
Houdiniの練習として「ネジ」を作ろうと思ったのですが、螺旋を作る方法をググっても自分が求めていた超初心者向けなシンプルな記事を見つけられませんでした。
そこでとにかくシンプルで汎用的な螺旋を作る方法として超初心者の自分に対するメモ用も兼ねて記事としてまとめます。
この投稿を読んで下さった方がHoudiniで単純な螺旋が作れるようになる事を目指しています。
参考にしたサイト
「Houdini ネジ」で検索した結果出てきたこちらのブログの記事を参考にさせてもらいました。
「螺旋」はどうやって作るか
Wikipediaによると、
3次元曲線の一種で、回転しながら回転面に垂直成分のある方向へ上昇する曲線である。
と書いてあるので、要するに点をクルクル回しながら上昇させれば螺旋になるようです。
ノード構成
ノード名 | ノードタイプ | 役割 |
---|---|---|
add1 | Add | 原点から半径分離れたpointを一つだけ作る(点を作る) |
copy1 | Copy and Transform | ↑のpointを螺旋状(回転しながら上昇)に並べながらコピーする |
add2 | Add | 全てのpointをつなぐ |
作成手順
1.元になるpointを作る
まず元になるpointを作ります。そのために**"Add"**ノードを使います。
**"Add"**ノードって何かを追加するために使うノードのような印象を受けるのですが、これを使えばとりあえずpointをひとつ作る事も出来ます。
ネットワークエディタでTABを押してノードを作成します。(ノード名はadd1とします)
まず、pointを一つ作りたいだけなのでNumber of Pointsは1にします。
次に、すぐ下のチェックボックスをONにしてPoint 0を使えるようにします。
Point 0のX要素に螺旋の半径(ここでは1)を入れます。
2.pointを螺旋状にコピーする
"Copy and Transform"って名前からしてコピーしながらトランスフォーム出来る名前のまんまのノードです。
ネットワークエディタでTABを押してノードを作成します。(ノード名はcopy1とします)
add1の出力をこのノードの入力に繋ぎます。
まずTotal Numberに121と入力します。
これでadd1ノードで作ったpointを121個のコピーを作ることになります。
つまり、螺旋を121個の点で作成することになります。
次にTranslateのY要素に0.05、RotateのY要素に15と入力します。
これによりコピーする度に15度回転して0.05ずつY方向にずれてコピーしてくれます。
3.全てのpointをlineでつなげる
**"Add"**ノードって何かを追加するために使うノードのような印象を受けるのですが、これを使えば並んでるpointをつなげて線を作る事が出来ます。
ネットワークビューでTABを押してノードを作成します。(ノード名はadd2とします)
copy1の出力をこのノードの入力に繋ぎます。
Polygonsタブをクリックして、その中のByGroupを選択します。
そしてGroupの中は空に、AddはAll pointsを選択します。
4.とりあえず完成!
"Display points"と"Display points number"の表示をOFFにして確認した結果がこちらです。
出来ました!やったね!
add1ノードとcopy1ノードで使ったパラメータの値を調整すると、螺旋の形状が変更出来ます。
とりあえず螺旋が作りたかった人はここで終了です。
サブネット化&パラメータ追加で調整しやすくする
add1とcopy1のパラメーターを調整すると螺旋の形が変えられるのですが、現在の状態だと形状が調節が面倒です。
そこでサブネット化して調整用のパラメーターを追加して使いやすくしていきます。
1.サブネット化
ネットワークエディタでCtrl+Aを押して、add1、copy1、add2とすべてのノードを選択して。Shift+Cを押して今作ったノードをサブネット化します。
2.調整用パラメーターの構成を決める
作ったsubnet1にパラメーターを追加していきます。
自分の場合は、次のような想定でパラメータの構成を決めました。
- ポリゴン具合をカッチリ決めたい
- Tubeノードと組み合わせてBooleanノードで形を切り出すために、形を揃えやすいように共通のパラメーター(radius, height, cols)を持ちたい
よって、以下のようなパラメーターを追加する事にしました。
Name | Label | Type | 役割 |
---|---|---|---|
radius | Radius | Float | 螺旋の半径 |
height | Height | Float | 螺旋の高さ |
cols | Columns | Integer | ひとつのループの分割数(SphereやTubeのColumnsと同じ意味) |
loopNum | LoopNum | Integer | ループの数 |
目的によっては違うパラメーターの持ち方をした方が使いやすいかもしれません。
その場合は色々考えて試してみてください。
3.調整用パラメーターの追加
subnet1ノードを選択した状態でパラメーターの右上にあるギアアイコンを押して**Edit Parameter Interface...**を押してパラメーターの編集ウィンドウが開いたら、以下のように上記の表のパラメーターを追加します。
追加したら、パラメータを以下のように設定しておきます。
- Radius = 1
- Height = 6
- Columns = 24
- LoopNum = 6
4.半径のエクスプレッションを設定
調整用のパラメータを元に、subnet内のノードのパラメーターを設定するようにエクスプレッションを組んでいきます。
subnet1をダブルクリックしてサブネット内のネットワークを表示します。
add1のPoint 0のXに、以下のエクスプレッションを設定します。
pointがradius分離れているのをクルクル回しながらコピーするので、つまり螺旋の半径になります。
ch("../radius")
確認のため、ネットワークの階層を一つ戻ります。
subnet1のRadiusパラメーターを変更すると、半径が変わるようになっていると思います。
5.螺旋の形を決めるエクスプレッションの設定
再びネットワークビューでsubnet1内に戻ります。
copy1には複数のエクスプレッションを設定します。
まずはTotal Numberです。
ここには螺旋を構成する頂点の数を指定します。
colsはループ一個のpoint数です。Y軸に一回転するとcols個の点が使われます。
それをループ数(loopNum)分コピーします。
また、ループの終わりに必要な分を**+1**します。
つまり以下のような記述になります。
ch("../loopNum")*ch("../cols")+1
続いてTranslateのYです。
ここには、一つコピーする度に移動する量を入れます。
最終的なサイズをheight**に合わせたいので、heightを螺旋の頂点数(loopNum*cols)で割って一つのpointがコピーする度に移動する量とします。
つまり以下のような記述になります。
ch("../height")/(ch("../loopNum")*ch("../cols"))
最後にRotateのYです。
ここには、一つコピーする度に回転する量を入れます。
一回転(360度)で、cols個の点になるようにしたいので、360をcolsで割ります。
つまり以下のような記述になります。
360.0/ch("../cols")
以上で完成です!
ネットワークの階層を一つ戻ってsubnet1のパラメータを変更してみてください。
形が調整出来るようになっています。
応用例
とりあえず、自分の目的は以下のモデルを作ることだったので、螺旋からネジを作ってそれを複製して使いました。
Houdiniでポケモンのコイル作ってみた。 pic.twitter.com/XxkE2gD9ES
— マメマメ (@mamemame360) 2018年12月19日
その他の方法
Sweepノードのtwistを使ってやる方法もあります。
こっちの方が冗長ですが応用はしやすいかもしれません。
BornDigitalさんのチュートリアル記事を参考に少し変更を加えています。
あとがき
自分の本職はプログラマで、Wrangleノードを使えば簡単に出来るのは重々承知なのですが、
それだとなんでもWrangleノードでやってしまえば良いことになります。
ですが、アート畑で同じようにHoudiniに興味があって勉強している人にそう言うと100%ウンザリした顔をされます。
そもそもHoudiniの練習にもならないと思いWrangleノードを使わずに作る方法を探していました。
ちなみに公式にVEXで螺旋を作るサンプルもあります。
http://www.sidefx.com/ja/docs/houdini/ref/expression_cookbook.html
自分もHoudiniを初めて半年弱しか経っていませんので、こういう定石っぽいものをたくさん集めていきたいと思っています。