Houdini Surface Shader – VOP Basic

シェーダはSHOPコンテキスト内で操作する

20140505_01_2

シェーダの作成

・Material Palette

20140505_01_0

左側のプリセットを右側のブロックにドラッグして簡単作成

・Network View

TABキーからシェーダーノード名を指定。
Houdiniのバージョンアップに伴い、デフォルトのシェーダ名が変更されているケースが散見される。
最も基本的なシェーダは Material Shader Builder で良さそう。

VOPの基本

20140505_01_1

シェーダアイコンをダブルクリックするとシェーダーを定義しているノードネットワークに入れる。

VOPノード

VOP内のノード表示はこんな感じ

20140505_01_3

ノードの左右端にはノードのコネクト用プラグが並ぶ。

・パラメータ名

フルネームが表示したければPreferenceのNetwork Editorオプションから設定

20140505_01_4

・Nodeコネクション

プラグクリックでコネクタを伸ばし始め、コネクト先プラグをクリックで接続
肩は色分けされているので、ひと目で分かる。

違う型のAttributeを接続する場合は間に「Float To Vector」などの変換ノードを挟む。

基本的な使い方

各種ノードを作成し、それぞれの出力をAdd VOPなどのオペレーターを使用して計算し、最終的にoutputノードへ接続して結果を出力する。

ノードの自動作成

各種入力プラグを中ボタンでクリックすると、よく使うノード(場合によっては小さなノードネットワーク)を自動作成できるようだ。

20140505_01_8

特徴的なのはPromote Parameterで、Parameterノードが接続されたパラメータは、親のShaderノード内にExposeされ、VOPネットワークに入らなくても触れるようになる。

各種ノード

・Parameter

外から値を入力する窓口となるノード。
Parameterノードを作ると、親ノードの中にParameterノードと同じ設定のパラメータが作成される。
親ノード側のパラメータを操作することで、VEX内のノードに与えるパラメータを直接操作できるようになる。

ExportをAlwaysに設定すると、他のコンテキストからこのパラメータを参照できるようになる。
また、こうすることで、VEXネットワーク内で入力パラメータも持つようになる。

・Constant

定数ノード。Typeを指定して様々な型の定数を出力できる。

任意のプラグを中クリックし、ポップアップメニューからConstantを選択することで、そのプラグに接続された状態でConstantノードが作成できる。

・Add/Sub/Multiply/Divideなど

一般的な計算ノード

型の違うパラメータ同士を計算する際は、入力の順番に気をつける必要がある。

20140505_01_5

multiply1はvector型を先に受け取ったので、出力もVector型(ベクトル積)
multiply2はfloat型を先に受け取ったので、出力はfloat型(スカラー積)

※実際に値を表示する方法がわからないのでどのような計算結果が返るかは現時点では不明

・Random

名前の通りの動作。
入出力のタイプをノード内で決定できる。

20140505_01_6

※VOPノードはこのように、ノード内で入出力タイプを切り替えられる場合が多いようだ。

・Lighting Model

シェーダへのライトの影響タイプを定義するノード。Lanbertian/Blinn/Phongなど、古典的なLighting Modelを選択できる。

Lighting ModelパラメータでVEX Specularを選択することで、独自の光沢を作成することができる。

VEXのデータ型

Constantで作れるデータ型は以下のような感じ

20140505_01_7

3Floats/Vector/Colorや、int/toggleなどのように、似ているデータ型が複数存在する。
カッコの中に型名が記載されているので、この型が合っているプラグ同士であれば接続できる。

Particles I&II&III

https://vimeo.com/8447016
https://vimeo.com/8447185
https://vimeo.com/8447373

Partコンテキスト

パーティクル操作のためのコンテキスト。
これを使わなくてもobjコンテキスト内ではパーティクルが作れた。

Partコンテキストを使うことでどんな利点があるのか気になる。

Location (POP)ノード

ポイントエミッタ

基本的なパラメータはpopnet-oldなどと同じ。

・Birth Groupパラメータ

生成されるパーティクルが格納されるグループ名

・Preserve Groupパラメータ

上流で作られたグループを保持し、このノードで作られるグループをフローに追加する。

・Velocityパラメータ(Attributes)

初速方向の決定

・Varianceパラメータ(Attributes)

初速のランダムベクトル。
±入力されたベクトルの範囲でランダム化される。

Position(POP)ノード

Velocity (POP)ノード

パーティクルの速度を変更するオペレータ
Velocity TypeをVectorにし、パラメータを

vector3($VX, $VY, $VZ) * 0.9

などとすると毎評価ごとに速度が0.9倍され減速するパーティクルが作れる

Acceleration (POP)ノード

Split (POP)ノード

パーティクルからパーティクルを発生させる。
これを使用して、任意のパーティクルから速度を持たないパーティクルを発生させれば、パーティクルの軌跡が作成できる。

Follow (POP)ノード

パーティクルをパーティクルに追従させる。

Source Groupで引き付けられる側のパーティクルグループを指定
Leaderタブ、Leader Groupで引きつける側のパーティクルグループを指定

引きつけの速度などはFollowタブで設定。
Stop At Leaderをオンにしておくと、追従後にパーティクルはストップする

Collision (POP)ノード

任意ノードとパーティクルのCollisionを検知できる。

Collosion Eventパラメータには、このCollisionが有効になった際に発生するCollisionイベントの名前を記入する。

このイベント名は、後で以下の関数などで使う。

popevent( “EVENT_NAME” )

この関数に与えられた名前を持つEventが発生した時、関数はTrueを返す。なので、別のSourceノードのImpulse Activationなどに仕込めば、Collisionイベント発生時にのみパーティクルを発生させるような事が可能。

Collect (POP)ノード

パーティクル版のmergeノード

Curl-Noise(POP)ノード

パーティクルにNoiseを与える。
Noiseの影響はUpdateタブでAdvection Typeから指定。
ポジションや速度、外力として与えるなど、様々な選択ができる。

popnet-oldオペレータ

Over Samplingを上げると、Constタイプで時間に対しスムースに作成されるパーティクルの間隔がスムースになる。

パーティクルの外観

20140503_01_0

・Sprite(POP)ノード

スプライトを設定
同じように操作しているつもりだけど、何故かうまくスプライトの割り当てができない。

20140503_01_1

 

バージョン違いによる差異だろうか。

チュートリアルでは、一度popnetに対してスプライトを当ててから、別のパーティクルに当て直しているように見えるこの手順は一旦スキップする。

・Instance(POP)オペレータ

オブジェクトインスタンス

・Render(POP)オペレータ

パーティクルをそのままレンダリングする際の見た目を決定する

Color(POP)オペレータ

パーティクルのカラーや透明度を指定する

Property(POP)オペレータ

任意のタイミングで、任意のアトリビュートを操作できる。

Trails Effect Tutorial

https://vimeo.com/5891547
https://vimeo.com/5891661

ボックスから発生するトレイルエフェクトチュートリアル

1・以下の3つを作成

・motionPath_curve
エミッターとなるボックスが沿うモーションパスカーブオブジェクト

・trail_emitter
エミッターとなるボックスオブジェクト

・trail_lines
トレイルエフェクトオブジェクトが入るGeometryノード

20140502_01_0

2・モーションパスにボックスを沿わせて動かす

trail_emitterのPath ObjectにmotionPath_curveを指定
Positionにスタートフレームで0、エンドフレームで1となるようにキーを打つ。
これで時間を動かすと、カーブに沿ってボックスが動くようになる。

20140502_01_1

3・Trailノードを使ってボックスの頂点の軌跡を取り出す

※この時、trail_emitter内のboxノードに直接Trailノードをコネクトしても、trail_emitter内に存在するbox自体は、ローカルな空間内では動いていないので軌跡が作成されない。
グローバル空間での動きを元にTrailを作成する必要がある。

trail_linesの中にObject Mergeノードを作成する。
このノードは、パスを指定してどこからでもジオメトリデータを取得できる。パラメータリストの下部で呼び込みたいオブジェクトのパスを指定する。

20140502_01_3

Transform情報はbox自身の移動情報を使用するので、以下のように設定する。

20140502_01_2

そして、Object MergeにTrailノードを接続すると、Trailが正しく有効になる。

20140502_01_4

20140502_01_5

4・エフェクトの発生点を作成する

trail_emitterを非表示にしておき、後面を選択後に削除。

blastノードが作られ面の削除が行われる。
blastノードのパラメータで、Delete Non Selectedをオンにする。
こうすることで、選択されていなかった面が削除される。

5・Trailで複製された面が持つ頂点同士を接続する

Trailノードのパラメータで、Result TypeをConnect as Polygonsにする

20140502_01_6

20140502_01_7

同じ番号を持つ頂点同士が接続される。

デフォルトの設定では、ここで作られるポリゴンのラインは閉じているため、急激なカーブを行う箇所などでは面が見えてしまう。
開いたカーブにするため、以下のパラメータをオフにする。

20140502_01_8

6・Trailが作るラインがいい感じの見た目になるようにパラメータを調整

20140502_01_9

20140502_01_10

上記のような設定にしてみた

7・Trailで出来たラインをNurbs Curveに変換する

Convertノードを作成し接続
Convert To を Nurbs Curveにする

20140502_01_11

8・ラインのパラメータ位置計算のため、rankアトリビュートを作成する

Attrib Createノードを作成。
Name を rankに

9・カスタムアトリビュートをビューポートに表示する

Dキーでディスプレイオプションを開き、Customの項目でNew text display option

20140502_01_12

20140502_01_13

ApplyやAcceptを押すと、Customの項目にrankが追加されたことがわかる。

20140502_01_14

これがオンになっていると、同名のアトリビュート値が各ポイント上に表示されるはずだが、なぜかされない。

ちなみに、このカスタム表示を使えば、各頂点上の法線方向なども視覚的にわかりやすく表示できるようになるらしい。

20140502_01_15

10・VOP SOP

VOP SOPを作成してコネクト

20140502_01_16

VOP SOPに入る

11・rankの値を使用するため、Parameterノードを作成する

20140502_01_17

ノード名はわかりやすいものにする

Nameはアトリビュート名
Labelはわかりやすいものにする

InvisibleがオフだとVOP SOPノードにパラメータが表示されてしまうのでオンにして隠しておく。

ノードカラーも、inputとVOP SOP内で生成されるものとで分けておくと良い。

12・RampParameterを作成し、コネクトする

Trailエフェクトのぶれ具合をramp制御したいのでRampParameterを作成し、コネクトしておく。

RampParameterノードは0〜1の値を受け取り、それぞれの値に応じた値を出力する。

20140502_01_22

Rampの動作は以下のようにしておく

20140502_01_18

Nameに$OSという名前の変数を使うと、ノード名そのものがここで作られるパラメータ名として使われる。VEX内部で生成するパラメータはこのパターンで命名するのが楽かも。

13・Turbulence Noiseノードを作成する

このノードを使用して、Trailのブレを作る

20140502_01_21

14・Noiseスケール用のParameterノードを作成する

Turbulence Noiseで作られた3軸のノイズ値を個別にスケールできるように、 3 Float型のParameterノードを作成。

この時、Default値は 1,1,1にしておく。(0,0,0 のままだと、Noiseがかかっていないように見えてしまう)

20140502_01_19

15・MultiplyノードにNoise計算用ノードをコネクト

20140502_01_20

16・Noiseと元々のカーブを加算する

最後に、Multiplyで作られたNoise成分と、元々のカーブのポイントを足し合わせる。

20140502_01_23

Multiplyの計算結果は、あくまでもノイズ成分。
これを、元々のカーブに足し合わせることで、Noiseの加わったランダムなカーブが出来上がる。

20140502_01_24

赤がモーションパスカーブ
緑がNoise加算前のTrailカーブ
白がNoise加算後のTrailカーブ

20140502_01_25

チュートリアルをアレンジしてレンダーしてみた

Houdini sidefx official Lesson12 Compositing

パーティクルアトリビュートを個別に取り出しやすくする

sourceノードにAttribCreateノードを接続する。

20140430_01_1

AttribCreate内でNameに任意のアトリビュート名。
Valueに変数名を使用することで、任意の変数に名前をつけて明示的に外に出せるようだ。

20140430_01_2

マルチパスレンダリング

Mantraノード内、Outputタブ。

20140430_01_3

Extra Image Planesで+ボタンから出力するパスが追加できる。
デフォルトで定義されているパスはVEX Variableの項目右端のプルダウンから簡単に指定可能。

VEX Typeは変数の型を指定。もともとVector型として定義されているパスをFloatなどで出力するとどうなるのか?後でテストする。

Channel Nameは出力されるファイル名のようだ。

Quantizeでピクセルのビット深度の指定。

この設定をしただけではマルチパスレンダリングされないので注意

Material Shader Builder

マルチパスレンダリングのため Extra Image Planeを追加したら、SHOPでMaterial Shader Builderを作成し、オブジェクトへアサインする必要がある。

これでもまだマルチパスレンダリングは行われない

20140430_01_4

VEXパラメータの追加

Material Shader Builderの中でParameterノードを追加し、Nameに先ほど作成したExtra Image PlaneでVEX Variableでつけた名前をNameパラメータに指定する。

20140430_01_6

ExportパラメータをAlwaysにしてレンダリングするとマルチパスレンダリングされたことがわかる。

20140430_01_5

ウインドウ上部のチャンネル名プルダウンから、表示するチャンネルを指定できる。

上図は、Velocityチャンネルを表示。

MPlayについて

Iキーを押すとカーソルの下にあるピクセルの各種情報が表示される

20140430_01_7

以下のボタンを押すと、現在表示されているチャンネルに含まれる値の範囲を最大限引き伸ばして表示できる。

20140430_01_8

イメージファイルへのレンダリング

mantraノードのProperties->Output

Output Pictureパラメータにファイルパスをファイル名込でセット。
拡張子を記入しておくと、自動的にその拡張子のフォーマットで書き出される。

ここにipとだけ記入しておくと、MPlayで直接レンダリングされる。

imgコンテキストを使用するコンポジット

コンポジットプロジェクトの設定は Edit -> Composite Project Settings
コンポジット作業は、imgコンテキスト内で行う。

コンポジット中の画像はComposite Viewで確認できる。

ノードベースのコンポジットソフトと同じように、素材ノードの下流に各種処理ノードをつなげて処理を進める。

まずはImage Networkノードを作り、カットごとなどある程度の単位でサブネットワークを作るのが良い。

イメージファイルの読み込みはfileノードから行う。

Channel Copyノードでイメージファイルから任意のチャンネルを取り出したり、取り出した画像にBlurやExpand,Limitなどといった画像処理ノードををつないでマスクを生成するなどしながら画像合成を行う。

20140430_01_9

20140430_01_10

レンダーノードのmerge

複数のレンダーノードを作成し、mergeノードにまとめると、mergeノードのRenderボタンからまとめてレンダリングできる。

Houdini sidefx official Lesson11 Dynamics

Rigid Body

剛体シミュレーション。
Rigid Bodyの作成は、Rigid Bodiesタブから RBD object 選択後、Rigid Body化するオブジェクトを選択し、Enter

Rigid Bodyの基本ノード構成

20140428_01_0

torus_object1に対してRigid Body化した直後

torus_object1の内側

20140428_01_1

通常通り、ジオメトリが作成され、restにつながっている。
restノードはソリッドテクスチャをオブジェクトへ追従させるために使うノードらしい。

dopimportノードは、別の階層にある DOP Networkへジオメトリデータを転送するのに使っている

20140428_01_4

Object Mask = dopobjscreatedby(“/obj/AutoDopNetwork/torus_object1”)

AutoDopNetworkの内側

20140428_01_2

dopimportで出力されたジオメトリデータをRBD Objectノードで受け取っている。

SOP Pathパラメータにて、どのジオメトリを受け取るか指定

20140428_01_3

SOP Path = opinputpath(“/obj/torus_object1/dopimport1”, 0)

Rigid Body Solver

実際にシミュレーションを行うノード。

20140428_01_5

Solver Engineパラメータで、使用するソルバを指定する。
おそらくBullet以外を使うことは殆ど無いんじゃないだろか

以降のコネクションには、ここでリジッドボディに関連するジオメトリをまとめるmergeノードと、重力等の外力ノードが並ぶ。
これに続けてWindノードなどをつないで外力を足すことも可能。

Ground Plane

無限遠のCollisionオブジェクトを足すことができる。

Rigid BodiesタブからGraund Plane。

20140428_01_6

20140428_01_7

Rigid Bodyオブジェクトの初期状態

各RBD ObjectノードのInitial Stateタブにて設定。

Collisionのパフォーマンス調整

RBD ObjectのCollisionsタブにて設定

20140428_01_8

Modeの変更可で処理の高速化ができそう。
Modeパラメータは、実際に各RBD オブジェクトがどのようなCollision形状を使用して衝突判定を行うかを決定する。

このCollision形状を確認するには、Show Collision Geometryをオンにし、一度初期フレームに戻る。

20140428_01_9

20140428_01_11

20140428_01_10

DivisionsパラメータでCollision形状の精度を調整する。
当然だが、極力少ない面の数で構成されるように調整するのが良い。

シミュレーションのパフォーマンス調整

AutoDopNetworkのパラメータで行う。
Sub Stepで1ステップを何分割して計算するか指定。
このへんはその他のシミュレーションツールと同じ考え方で良さそう。

剛体の振る舞い調整

RBD ObjectのPhysicalタブで行う。
このへんもMayaなどと同じ考えで設定できそう。

※Mayaにないパラメータ
Dynamic Friction Scale:静止摩擦が限界を迎えた後の摩擦係数。
説明を読む限り、Frictionは静止摩擦で、それに対してこの数値を掛けあわせた値が動摩擦係数として動作するということらしい。
よって、この値が0の場合は、滑り出したら摩擦係数0の状態で動作するようになる。逆に、1の場合は常に静止摩擦の値で摩擦係数が発生することになる。
Temperature:温度。浮力や発火の検知に用いる値らしい。
例えば、燃料オブジェクトにこの剛体が接した時、燃料オブジェクトの発火温度をこの値が上回っていたら発火させる。
この発火処理がどのように行われるかは現時点では不明。

RBD Objectの追加

追加したいオブジェクトを選択し、通常通りRBD Objectを作成すると、AutoDopNetworkにRBDオブジェクトが追加される。

20140428_01_12

RBD Objectはいったんmergeノードにまとめられた上で各ソルバノードへジオメトリの出力を行うようだ。

これは、Static RBDオブジェクトの追加も同様。

20140428_01_13

閉じていない形状のRBDオブジェクト

デフォルト設定では、RBDオブジェクトは閉じていない形状でも閉じてい状態で計算される(Bulletの制限?)

20140428_01_14

ボールはチューブの内側に落ちず、チューブが持つボリュームに乗る。
これを防ぐには、チューブの表面に厚みをもたせ、形状を閉じておく必要がある。

カーブ上に散布するオブジェクトの向き

ここでは、散布されたオブジェクトをそれぞれ次のオブジェクトに向けるある一点のオブジェクトに向いてほしい方向は「次のポイントの位置-現在のポイントの位置」で表わせる。

pointノードについてもう少し

pointノードのinput2は、ポイント参照用のオブジェクトを入力できる。
参照用オブジェクトを使用すれば、法線方向の計算などで使用することができる。

20140428_01_15

上図の例では、上見えているカーブを複製し、複製されたカーブを少し下にずらしている。
複製されたカーブなので、各頂点番号は一致している状態。

ここで、上のカーブをpointノードのinput1に、下のカーブをinput2へ接続し、pointノードのNormalに以下のエクスプレッションを仕込む。

NormalX : $TX2-$TX
NormalY : $TY2-$TY
NormalZ : $TZ2-$TZ

$TX2はinput2側の頂点位置を指す。
こうすることで、input1の各頂点法線は、input2の各頂点との差分ベクトルを持つようになる。

Dominoチュートリアル

20140428_01_16

このチュートリアルでは、まずドミノピースを並べるためにカーブを作成する。その後、カーブをResampleし、等間隔で頂点をもたせる。
最終的には、このカーブが持つ各頂点上にピースを複製して散布する。

Resample済みのカーブを受け取るSortノードを作成し、ソート方法をShiftにした上でOffsetパラメータを変更すると、各頂点番号が循環する。

ここでは、この性質を利用して、全く同じ形状で一つ頂点番号がずれたカーブを法線方向計算のための参照先として利用する。

20140428_01_17

頂点数が同じで、元の頂点の並びが同じカーブ同士なら、片方のカーブ上にある頂点番号を一つシフトすると$TXと$TX1の差は、ちょうど隣り合う頂点の位置の差分となる。

よって、この値をNormalに与えれば各頂点の法線は、強引ではあるが次の頂点方向を向くようになる。

この時、末端のポイントだけは正しい方向を向けられないので、DeleteノードをPointノードの後ろに配置し、ポイントの削除を行う。

オブジェクトの頂点上にRBDオブジェクトを散布する

任意のオブジェクトを選択した状態で以下を押す

20140428_01_18

すると、ダイアログが開く。RBD Packed〜 と RBD Point〜の違いが不明なので調べる。

その後、散布したいオブジェクトを選択し、Enterキーで決定。

散布された各オブジェクトは、通常通りRBDオブジェクトとして動くようになる。

あとは、地面を配置してドミノをスタートさせるオブジェクトを作り、最初のピースを倒すだけ。

RBD Object と RBD Fracture Object

RBD Objectは、一つのジオメトリに複数ピースのジオメトリが含まれている場合、それらが一塊でなかった場合でも一つのRigid Bodyオブジェクトとして扱われる。

20140428_01_19

RBD Fracture Objectは、1ジオメトリ内に含まれるすべてのジオメトリを個別のRigid Bodyオブジェクトとして扱う。

20140428_01_20

RBD Glue Object

糊付けされたように、もともと結合力を持っているRigid Bodyが作成できる。例えば家具など、力が加わることで破壊され、他と切り離されるまでは結合を保とうとする振る舞いが作成できる。

シェルフ内で当該機能が見つけられなかった。
別の方法で作る方法を探る。

RBD Pin(Rigid Body Constraint)

剛体に制限を与えることができる。
以下を押す。対象となる剛体オブジェクトを選んでEnter、Pinの位置を選択し、もう一度Enter

20140428_01_21

RBD同士をPinでつなぐ

RBD Pin作成時に2つのRBDを選択すれば、それぞれがPinで繋がれる

20140428_01_22

Rigid Pin Constraintノード

20140428_01_23

Constrained Objectはコンストレインをうけるオブジェクト
Goal Objectは、コンストレインを与えるオブジェクト

Goal Objectが空欄だとGoal Locationで定められた位置にゴール位置が固定される。

RBD Spring Constraint ノード

バネで剛体をつなぐコンストレイン。

20140428_01_24

20140428_01_25

Limit Forceは、バネが切れる力のしきい値のようだ。
低めの値にしておくと、一定の速度がかかった時にバネが消えて、剛体は自由落下する。

20140428_01_26

20140428_01_27

その他のRigid Body Constraint

RBD Hinge Constraintや、RBD Angular Constraint等がある。
使用するソルバによって使えるコンストレインが変わるらしい。

破壊可能なRigid Body

RBDを作成後、Make Breakableを押す

20140428_01_28

破壊のパラメータは Fracture Parameterノード内で操作する。

20140428_01_29

20140428_01_30

20140428_01_31

Houdini sidefx official Lesson10 Particles

Particleノード

20140427_01_0

入力は、左から順にソースオブジェクト、コリジョンオブジェクト、フォースオブジェクト。

パーティクルは、ソースオブジェクトのポイントの位置からIDの順にしたがって発生する。

リアルタイムプレイバックオプション

あまり変わってるように見えないけど、タイムスライダ右側の時計アイコンのオンオフで全フレームを極力高速に連続再生するか、設定されたフレームレートを守って再生するかを決められる。

20140427_01_1

パーティクルの初期設定

ソースオブジェクトからpointノードに接続し、Particleタブの中で初速等を設定する。

20140427_01_5

20140427_01_2

初速に Y=-9.8を入れてみたところ

20140427_01_4

20140427_01_3

パーティクルをソースオブジェクトの法線方向に飛ばす

ソースオブジェクトにコネクトされるpointノードで、standardタブにあるNormalの項目をAdd Normalにする

20140427_01_6

20140427_01_7

この法線パラメータも初速として考えることが可能。
初速と同様にY=-9.8とすると全く同じ動きをする。

パラメータ名と動作をより正確にマッチさせるなら、Velocityパラメータに$NX,$NY,NZを元にするエクスプレッションを仕込むのが正しい気がする。

パーティクルをランダムな位置から発生させるには

ソースオブジェクトをScatterに接続し、オブジェクトの表面に一度パーティクルを散布し、散布されたパーティクルをパーティクル発生点にする。

Sortノード

入力されたコンポーネントのIDの並びを任意のルールでソートする。
例えば、ソースオブジェクト上のパーティクル発生位置を固定しながら、発生順だけをランダム化したい場合に使うと便利。

Collisionオブジェクト

パーティクルが衝突するオブジェクト。
このオブジェクトは体積を持っているべき。

形状を作成したら、particleノードの2番目の入力にコネクトする

デフォルトでは、Collisionオブジェクトにパーティクルがヒットした際の動作は「消滅」に設定されている。

Hit Behabiour = Die On Contact

このパラメータをBounce On Contactに設定すれば、Collisionオブジェクトにヒットしたパーティクルが跳ね返るようになる。

20140427_01_8

20140427_01_9

Collisionアトリビュートは Gain Tangent/Normalのようだ。
Collisionヒット時にそれぞれの方向にどの程度の倍率で力が変化するかを指定できる。

+/- Limit Planeパラメータは、強制的に発生させるCollisionバウンディングボックスと言える。多分オブジェクトを使用するCollisionより高速かつパーティクル抜けがないので、室内シーンなどでは積極的に使うのがいいように思う。

20140427_01_10

上図は、-Limit PlaneをCollisionオブジェクトより高い位置に設定した例

パーティクルのSplit

Collisionヒット時にサブパーティクルを発生させることができる。
設定は、Splitパラメータから行う

Hit Behaviour=Die On Contact かつ Split=Split On Death に設定すると、単純にパーティクルがCollisionヒット時に分裂するような状態が作れる。

Stateパラメータ

Start Time:シミュレーション開始までの秒数
Prerole Time:シミュレーション開始時点までに事前計算を行っておく秒数。カットの開始時にある程度パーティクル数を出しておきたい場合に使用する。
Time Inc:パーティクルの評価タイミングの精度。細かくすればするほど評価精度が高まる。通常は1/$FPSで良くて、早過ぎるパーティクルなど、精度が求められるパーティクルだけ高精度化するのがいい。

ソースGeometryの変形

Particleノードの Behaviourパラメータを Modify Source Geometry にすると、ソースオブジェクトの頂点が、発生したパーティクルに追従するようになる。この性質を利用すれば、ソフトボディが簡単に作れそう。

パーティクルの寿命

Life Expectはパーティクルの寿命(秒)
Life Varianceはパーティクル寿命のランダム幅(秒)

Magnetノード

任意のGeometryをMetaBallによって変形できるノード。
チュートリアルでは、雨メタボールをパーティクル上にコピーし、メタボールがヒットした位置の頂点を盛り上げる変形を行うようにした

パーティクルの発生数に関して

パーティクルの発生数に関するアトリビュート

Impulse Activation:0=パーティクルは発生しない、それ以外は発生する。
Impulse Birth Rate:評価タイミングごとに発生させるパーティクルの数

Const Activation:0=パーティクルは発生しない、それ以外は発生する。
Const Birth Rate:一秒間に発生させるパーティクルの数

Particle -> Poly Line -> Skin -> Polygon Mesh

20140427_01_11


パーティクルの発生点として2つのポイントで構成されるラインを作成


ラインの中心にピボットを移動し、transformにつなげて回転させる。


このオブジェクトをパーティクル発生源にし、Initial Velocityを持たせて移動するように設定する。この時、Impulse Activationを1,Impusle Birth Rateを$NPTとし、ソースオブジェクトが持つ頂点数分を毎フレーム生成するように指定。


パーティクルをAddノードに接続し、By GroupタブでAddパラメータを Groups of N Pointsにし、Nを2にする。
こうすることで、パーティクルが2つ発生するごとに一つのグループにまとめられ、それぞれが別のPolyLineオブジェクトとして扱われるようだ。


Skinノードにコネクトし、面を貼って完成

popnet内でのパーティクルグループ

popnetノード内で、パーティクルのグループを作れる。

groupノードを作成し、Createタブで新規作成するグループ名を Group Nameに入力、Createタブ内、Ruleタブでグループに含める条件を入力することで、条件に当てはまるパーティクルをここで作成したグループに含めることができる。

20140427_01_12

下図は、パーティクルIDを走査し、偶数と奇数でグループを分け、それぞれのグループに別々のカラーとフォースを割り当てた例。

ColorノードやForceノード内で、Source Groupパラメータに、ここで作ったグループ名を入力することで、グループごとの編集が可能になる。

Groupノード内で Ruleタブ内にあるEnableを忘れずにオンにしておくこと。これを忘れると当然効果が現れない。

20140427_01_13

なお、パーティクルの寿命が尽きた時、全パーティクルが持つIDが変化してしまうため、一工夫して変化させない仕組みを作る必要があるようだ。

Houdini sidefx official Lesson9 Custom Shaders

VOP SOP

頂点を直接操作するためのノード
オブジェクトの変形などができるようだ

20140426_01_0

フルネームでアトリビュート名を表示する

Edit -> Preferences -> Network Editor, Nodes and Trees

で、以下のオプションをオンにする。

20140426_01_1

20140426_01_2

こんなかんじでフルネーム表示される。

アトリビュートの型

アトリビュート名の左右にあるボックスは、コネクタであり、値の型ごとにカラーが決まっている。このへんは他のDCCツールのノードエディタと同じ概念。

異なる型同士を接続sる場合は、変換ノードを間に挟む。
変換ノードには、Float to Vector等がある。

20140426_01_3

各コネクタの上にカーソルを置いて待つとコネクタの詳細情報がポップアップする

20140426_01_4

20140426_01_5

20140426_01_6

これは、型の確認に使える。

VOP SOPノードのボタン

20140426_01_7

ノードの右側にはボタンが有る。
左から順にデバッグ/バイバス/表示モード切り替え。

デバッグは後に説明がありそう
バイパスはそのノードを一時的に無効化する
表示モードは、全アトリビュート表示、コネクト済みアトリビュートのみ表示、全アトリビュート非表示を切り替えられる。

頂点移動の例

20140426_01_9

Noiseを使用してGridを変形する。

20140426_01_8

ここでやってること


入力されたメッシュであるglobal1が持つ頂点からそれぞれ Position(Vector)を取得し、Noiseノードに渡す。この時、特にグループなどが指定されていなければ、global1には入力されたメッシュ上にある全頂点が含まれる。


Noiseノードの計算結果をDisplacementノードに渡し、移動後の頂点位置を出力する。Displaced Position(Vector)


VOP SOPの計算結果を出力するためのOutputノードに、変形後の頂点位置を渡すことで、変形が完了する。

VOP SOPの使い方考察

見たところ、VOP SOP内ではトポロジの変更を行うノード(smoothやsubdivideなど)が作れないようだ。
よって、VOP SOPはすでにあるメッシュなどに対し、何らかの処理をするためのものだと思う。
トポロジ変更はVOP SOPの上流で完了させておく必要がありそうだ。

シェーダーネットワーク

shopでMaterial Shader Builderを作成

20140426_01_10

このノードの内側に入るとVOP SOPと同じ要領でシェーダーネットワークを編集できるようだ。

20140426_01_11

Global Variablesノード

出力したい内容に応じて使用する入力値が異なるので、Global Variablesノード内のアトリビュートを適宜切り替えて使用する。
VOPノードの動作は、このノードから出力される値をもとに行われるようだ。

Surface Modelノード

一般的なシェーディングノード。
だいたいこれを使っとけば問題ないらしい。
ダブルクリックすると中身を見ることができる。すでに複雑なネットワークが組まれていることがわかる。

既存のシェーダノード内にあるネットワークを編集する

20140426_01_12

ノードのラベル部分を右クリックして表示されるメニューから、Allow Editing of contentsを選択すると、ノード名が赤色になり、内部のノードネットワークが編集可能になる。

大体の流れとしては、Global Variable → 任意のチャンネルごとに見た目調整処理 → Surface Model → Surface Output → Collect の順にノードをコネクトすれば良さげ。

アトリビュートのPromote

Material Shader Builder内に存在する各ノードの中から、任意のパラメータへのエイリアスをMaterial Surface Builderノードへ持たせることができる。

外に出したいプラグを中ボタンクリックし、Promote Parameterを選択

20140426_01_13

こうすると、ノードのパラメータの左側に突起が出現し、Promoteされたことがわかる。

20140426_01_14

また、Material Shader Builderノードのパラメータを確認すると、パラメータが追加されたことがわかる。

20140426_01_15

また、Promoteは、パラメータリストに表示されている各パラメータの右端にあるボタンからも行える。

20140426_01_17

20140426_01_16

ノード内の未コネクトパラメータをまとめて外にだす場合は、ノードラベル右クリックから Create Input Parameters を選択する

Promote済アトリビュートのExpose

Promoteは、実際には、実体アトリビュートとアトリビュートへのエイリアスの間に値を中継するためのノードが挿入されて行われる。
ノードのPromote済みプラグを中ボタンクリックし、Expose Input Node を選ぶことで、中継ノードが表示される。

20140426_01_21

上図はdisplacementnml1のscaleアトリビュートはPromote済みで、それをExposeした様子。

この中継ノードを操作すると、値の範囲やタイプなど、パラメータの振る舞いを変更することができる。

Propertiesノード

任意のパラメータを持たせるためのデフォルトでは何のパラメータも持たないノード。Edit Parameter Interfaceで任意のパラメータを追加して使用する。

MaterialパラメータをGeometryノードに渡す

GeometryのMaterialパラメータ欄右端のプルダウンから以下のメニューを選択すると、geometry内のmaterialタブにシェーダが持っているパラメータのエイリアスがまとめて表示されるようになる。

20140426_01_18

20140426_01_19

この操作により外へ出されたパラメータは、マテリアル本体が共有されていても、値は共有されないようだ。

つまり、ひとつのシェーダを使いまわしてバリエーションを作成することができる。

これが、アトリビュートとチャンネルの違いということなのだろうか?
ちょっとぴんとこないので、あとで調べる。

オブジェクト内に直接シェーダーを埋め込む

オブジェクトの内側で SHOP Networkノードを作成するとオブジェクトに、シェーダーを埋め込むことができるようだ。

その後、GeometryノードのMaterialタブにて使用するシェーダーを選ぶ際、以下のようにオブジェクトツリー内のシェーダーが選択できる。

20140426_01_20

また、この時、Export Relative Path を選択してからマテリアル指定を完了すると、相対パスでマテリアルが指定されるため、Geometry自体が階層を移動してもマテリアルのアサインは保たれる。

Displacementの最適化

Displacementはデフォルトの設定では、欠けが発生するなどして、正しくレンダリングされない(チュートリアル中に理由が詳しく述べられているようだけど、よく聞き取れず)

これを回避するためには、Propertiesノードを作成し、レンダリング用の特別なアトリビュートを作成と、シェーダネットワーク末端のCollectノードへ接続する。

アトリビュートの追加はPropertiesノードで通常通りEdit Parameter Interface

For Renderingタブ → mantra → Shading → Displacement Bound

20140426_01_22

20140426_01_23

20140426_01_24

Displacement Boundの値を上げることで、精度が上がり、正しくレンダリングできるようになる。

20140426_01_25

それで出来た草シェーダ

VEXとVOP考察

VEXは、Vertex Expression?
VOPで作成するノードグラフは、実際にはVEXコードをグラフィカルに表示しているだけのようだ。

また、Material Shader Builderのパラメータを見ると Compilerの項目がある。これが意味するところは、リアルタイムにVEXがコンパイルされ、最適化された状態で常に使用されるということなんじゃないだろうか。

VEXのコードを表示するには

VOPの操作による処理を記述できるノードを右クリックし、View VEX Code を選択する