Houdini楽しんでますか?ぼくはありがたいことに忙しい日々を過ごしています。 今回はとても小さなTipsのご紹介ですが、広範囲で使える知識なのでご存じなかった方はぜひ今後使ってみてください。
今回のテーマは上記画像に尽きるのですが、一行目のVEXが「何をしているか」がわかりますでしょうか。わかってればこの記事から得られることはありません(笑)
しかし、もし「アトリビュートの前に型が書いてある…?」みたいな感じでしたらぜひ引き続き読んでみてください。アトリビュートをひとつ深く使いこなせるようになるかと思います。
目次
- 目次
- シーンファイル配布
- 基礎
- デフォルト値の指定をしないとどんな問題が起こるか
- デフォルト値を明示的に指定しよう
- 当然ながらAttribute Createでもデフォルト値は設定できます
- 線形補間のコントロールにも便利
- まとめ
シーンファイル配布
シーンファイルはこちらからダウンロード可能です。
シーンの作成環境は下記のとおりです。
- Windows10
- Houdini 18.5.408
基礎
まずはアトリビュート自体のお話。簡単にふたつのノードでポイントアトリビュートを与えるシーンを作ってみました。
if(@P.x > 0) @test = 5;
VEXコードは一行。これは説明不要かと思いますが、念の為簡単に解説します。
最初のif文で「ポイントのX座標がゼロより大きいかどうか」を判定しています。つまりポイントの位置がビューポートでX座標ゼロより右側にあれば条件式はTrueになり続く@test = 5
が実行されます。
つまり、X座標がゼロより右側にあるポイント全てにtestというアトリビュート5が付与される1ということです。
ここで質問です。ifの条件を満たさないポイント、つまりゼロより左側にあるものはアトリビュートが作られないのでしょうか?
答えはtestアトリビュート0が付与されます。ビューポート上でもジオメトリスプレッドシートでも確認できますね。
この勝手に作られる0という値をコントロールしようというのが今回のテーマです。
デフォルト値の指定をしないとどんな問題が起こるか
回避方法はいくつかあるのですが、ここではデフォルト値を明示的に指定しなかったため予期せぬ問題が起こってしまったケースを見ていきましょう。
グリッドを作る
Subdivideする
Sortでプリミティブナンバーをランダムにする
プリミティブナンバーをアトリビュートとして保持する
i@primid = @primnum;
プリミティブを削除する
自分で作ったパラメータ、target_idとprimidアトリビュートが等しいとき、プリミティブ(面)を削除します。
if(i@primid == chi("target_id")) removeprim(0, @primnum, 1);
target_idを0から15まで変更してプリミティブを削除する方法は本来良い手法ではないのですが、解説の都合上使用しています
問題なさそうですね。しかし、Mergeで他のジオメトリをまとめたあとにプリミティを削除する処理を入れるとどうなるでしょう?
アトリビュート作成前にストリームを分岐させた場合
アトリビュートを付与しているノード(attribwrangle_primid)の前にストリームを分岐させた場合、primidが付与されていないジオメトリ(分割前の大きいグリッド)ができるので自動的にprimid = 0
が付与されます。
デフォルト値を意識しないと意図しない結果に
primidを元に削除すると、primid==0
のプリミティブが重複するので同時に消えてしまいます。これが意図した動作であればOKですが、右の大きいグリッドは常に消したくない場合はどうすればよいでしょう。
デフォルト値を明示的に指定しよう
下記コードの1行目はデフォルト値の明示的な指定だったわけですね。
int @primid = -1; //here i@primid = @primnum;
このようにデフォルト値を指定すると大きいグリッドが事故で削除されることを防ぐことができます。
当然ながらAttribute Createでもデフォルト値は設定できます
今回のVEXコードと同様の設定は下記パラメータで実現2できます。
線形補間のコントロールにも便利
HoudiniではResampleやClipを用いてアトリビュートの線形補間する(中間をリニアな値で埋める)ことが多々ありますが、そのレンジもアトリビュートのデフォルト値を利用することで柔軟にコントロールすることができます。
まずは基本のやり方から確認していきましょう。
ポイント数2のLineを作成する
ビューポート上水色の数値がポイントナンバーを示しています
任意のポイントにアトリビュートを設定する
Attribute WrangleのGroupにポイントナンバーを指定してWrangleの適用範囲を限定します。ここではポイントナンバー1に対して@pid = 1;
を実行しました。
繰り返しますが、デフォルト値を指定していないので他部分(つまりここではポイントナンバー0)には自動でpidアトリビュートゼロが付与されます。
ビューポート黄色の数値がpidアトリビュートを示しています
Resampleを接続
ご覧の通り、0-1の範囲でアトリビュートが補完されているのがわかりますね。これは非常によく使うテクニックですので慣れていない方はこれを期にぜひ覚えておくと良いでしょう。
デフォルト値を設定する
LineSOPに続けてAttribute Wrangleをつなぎ、下記コードを実装しましょう。
float @pid = -1; @pid = 1;
ポイントナンバー1に対して@pid = 1;
を実行するところは同じですが、1行目に初期値-1を設定していますね。これによりポイントナンバー0のpidは-1になります。
Resampleを接続
今度はアトリビュートが-1~1の間でマッピングされました。0から1、-1から1、-1から0などのレンジはケースバイケースで使用したい場面が異なりますのでうまく活用していきましょう。
まとめ
非常に基本的な内容でしたが、アトリビュートのデフォルト値は大切だよ。気をつけていないと事故るよ。というお話でした。
Houdiniを使うということはアトリビュートを変更するということとほとんど同義なので、どんなときもスマートにアトリビュートをコントロールしたいものですね。