このチュートリアルは「【初心者向けHoudiniトライアル009】コンストレインネットワークを調整する」の続きです。
使用するHoudiniバージョン
Houdini 18.0.460
レンダリングに必要な設定を追加
前回作成したガラスにマテリアルとライトを設定し、レンダリングしてみます。
- 1フレームに移動します。
- ネットワークをObjectsレベルに移動します。

- ガラスのオブジェクトを選択し、パラメータエディタを確認します。
- Transform横にあるRenderタブをクリックします。

このジオメトリはガラス単体でできているので、オブジェクト全体にマテリアルを割り当てます。
といって、まだ割り当てるマテリアルを作成していないためマテリアルパレットでマテリアルを追加します。
- ネットワークエディタの横にあるMaterial Palatteとかかれたタブを選択し前面に表示します。

ここではすでに数種類の役立つビルトインのマテリアルが用意されています。
- Glassから、Glassをドラッグします。

このGlassマテリアルは、Principled Shaderマテリアルです。
Principled Shaderマテリアルは、パラメータの少ない直感的なアーティストコントロールだけで、ほとんどのルックの作成が可能な"物理的に妥当"な"万能シェーダ"です。
- 作成したglassマテリアルをダブルクリックします。
マテリアルをダブルクリックすることで、パラメータウィンドウに該当のマテリアルのパラメータが表示されます。
下記のようにこのglassマテリアルはPrimcipled shaderで作成され、パラメータがすでに設定済であることがわかります。

ネットワークエディタをみてみると、matというネットワークに移動していることがわかります。また、ネットワークエディタにはVEX Builderという記載があります。

マテリアルは、VOPによるシェーダの定義とパラメータユーザインターフェースが含まれたデジタルアセットになっています。VOP とは Vector OPerator の略となり、パーティクルや頂点などのポイント情報を処理するために、VEX を用いて演算を行うことができます。VEX とは Vector EXpression の略で、Houdini独自のスクリプト言語です。
しかし、既にここでは値がプリセットされたものをそのまま使用するため値を変更しません。
このマテリアルを、ガラスオブジェクトに割り当てます。
- ネットワークエディタのツールバー右端にある矢印をクリックするとこれまでのロケーション履歴をみることができます。
- /objを選択し、Objectsネットワークに移動します。

- ガラスオブジェクトを選択し、選択ボタンをクリックします。

- Choose Operatorウィンドウが開くので、matの+マークを展開し、その下にあるglassを選択します。
- Acceptをクリックします。

これでガラスオブジェクトにマテリアルを割り当てることができました。

次にライトを作成します。
- Light and CameraシェルフからEnvironment Lightをクリックします。

ObjectsレベルにEnvLightが追加されました。

- ライトを選択します。
- パラメータウィンドウにてLightタブを開き、Environment Mapの横のボタンをクリックします。

- Choose Imageウィンドウが開くので、左下のウィンドウにて$HFS/houdini/pic/hdri/を選択します。
- 3つのHDRIが表示されるので、一番下のgarageというものを選択します。
- Acceptをクリックします。

$HFSはHoudiniインストールディレクトリを意味する環境変数です。
次にカメラを用意します。
現在透明なマテリアルを割り当てているため、ビューポートでオブジェクトが見えないかもしれません。
- wキーを押して、ワイヤーフレーム表示に変更します。
- カメラを操作し、レンダリングしたい位置にカメラを動かします。

- Ctrlキーを押しながら、シェルフのカメラアイコンをクリックします。

現在の位置に新しいカメラが作成されます。ビューポートの右上がcam1となります。

そのままカメラを動かしてしまうと、すぐに元のカメラに切り替わってしまいます。レンダリングカメラの位置、回転を調整したい場合、カメラをロックする必要があります。
- 右側のツールバーから鍵のアイコンをクリックします。

これでカメラの選択がロックされます。

- カメラの調整後、鍵アイコンを再度クリックしてロックを外してください。
ロックを外し、カメラを動かすと、移動したカメラはレンダリングに使用するカメラではなくビューポートをみるためのカメラになります。

レンダリング
それではRender Viewでレンダリングを行います。
- 現在表示しているScene Viewの横にあるRender Viewタブを選択します。
- カメラを作成したcam1に切り替えます。

- Renderボタンを押してレンダリングを実行します。
実際にレンダリングを行うと1フレーム目でまだガラスはわれていないのにすでにひびが入った状態であることがわかります。

実際にものがぶつかって破片同士が離れるまで、1つの連続したオブジェクトだと見せたいためノードを追加します。
離れるまで1つに!RBD Disconnected facesを追加
RBD Disconnected Facesのドキュメントに以下の記載がございます。
・・・・・
ガラス粉砕でよくある問題は、割れていないガラスの破片に細かい内側フェースがある時に起こります。 ガラスは透過サーフェスなので、この内側フェースはレンダリングで問題を引き起こす可能性があります。 このような類の問題を解決するには、粉砕の後にRBD Connected Faces SOPを適用することです。 このノードは、粉砕ジオメトリの内側フェースのプリミティブ番号と、反対側のフェースまでの距離を記録します。 この情報を利用して、RBD Disconnected Faces SOPの Delete Connected モードを使って、割れていないガラスの破片の内側フェースを削除するかどうか決めることができます。
・・・・・
- RBD Material Fractureの直下にRBD Connected Facesを追加します。

このノードは粉砕ジオメトリの内側フェースの反対側にあるフェースのプリミティブ番号とそこまでの距離を格納します。繋がった内側フェースに関する情報を格納するので、それらのフェースがさらに下流のプロセスによって分離されたかどうかを判断するのに役立ちます。
- RBD Connected FacesのCreate Constraintsを無効にします。
これが有効だとコンストレインが新たに作成されてしまうため無効にしておいてください。

Geometry Spreadsheetを確認するとプリミティブアトリビュートとして、faceidとprimdistが追加されています。
faceidは、繋がったプリミティブ番号が格納され、primdistには、プリミティブの中心間の距離が格納されます。

このfaceidとprimdistを元に破片が離れたのかくっついているのか判断しますがこのままでは使えません。
現在、RBD Bullet Solverで出力されるのはパックプリミティブになっています。
- RBD Bullet Solver上にマウスカーソルをおくとリングが表示されます。
- この左側にあるiアイコンをクリックすると、ノードインフォが表示されます。


ここで持っているアトリビュートを確認してもfaceidやprimdist自体が存在しないことがわかります。

つまり、パックプリミティブをアンパックして通常のデータに戻す必要があります。
- RBD Bullet Solverの下にUnpackノードを追加します。

- ノードインフォを確認しアトリビュートが存在することを確認します。

次に問題となるのはパックする前と後で各プリミティブ番号は同じなのかということです。プリミティブ番号がアンパック後変化してしまうとせっかく保存しているfaceidとprimdistを元にくっついているのか離れているのかを設定できなくなります。
プリミティブ番号をチェックしてみましょう。
- 画面右側にあるツールバーで下記のアイコンをクリックします。ポイント番号と間違えないように注意!

- まず、RBD Connected FacesにDisplayフラグを設定しプリミティブ番号を確認します。

- 次にUnpackにDisplayフラグを設定しプリミティブ番号を確認します。

番号が変わってしまうことがわかります。そこで、Unpack後、ソートできるようにアトリビュートを追加します。
- そこでRBD Connected Facesの後ろにenumrateノードとRBD Constrain Propetiesノードを追加しました。
enumrateは1つの入出力しかもっていないため、RBD Constrain Propetiesを追加しました。

Enumrateノードは、プロパティのAttributeで設定したアトリビュート(ここではindex)にGroup Type(ここではPrimitives)のアトリビュートの値を連番のIntger(整数)に設定します。

Enumrateノードを選択し、Geometry Spreadsheetを確認するとプリミティブにindexが追加され0から始まる連続する数字が設定されています。

- 追加したRBD Constrain PropetiesではせっかくのあでGlueのStrengthを調整し、ばらつきを持たせました。

- unpackの下にsortをします。

- sortのプロパティにて、Primitice SortをBy Attributeに設定し、Attributeをindexに設定します。

これで各プリミティブの番号がソートされました。
RBD Connected Facesの時のプリミティブ番号と

Sortのプリミティブ番号を比較すると同じプリミティブ番号が設定されていることがわかります。

- プリミティブ番号を揃えた後に、RBD Disconnected facesを追加します。
RBD Disconnected facesは、繋がったフェースが分離されたタイミングを検知します。その結果をアトリビュートとして格納したり、または、繋がった/繋がっていないフェースを削除します。

- プロパティにて、ModeをDelete Connectedに変更します。
これでつながったプリミティブが削除されます。つながっているかどうかはDistance Attributeに設定したprimdistがDistance Thresholdの値を超えるかどうかで判断されます。

これで準備が完了しました!
- Render Viewに切り替え、Renderボタンをおしてレンダリングします。
1フレーム目では全くひびがなくなりました。

- レンダリングが終わっていない場合、下記の赤い×ボタンをおしてレンダリングを中断します。

- アニメーションを再生し、ガラスが崩れ始めたあたりに移動します。

- Render Viewでレンダリングします。
砕けて離れた部分にはひびがきちんと入ります。

さらにフレームを進めレンダリングします。
RBD Disconnected facesに設定したDistance Thresholdの値以下の場所は内側のフェースが削除され、ひびがはいらないことがわかります。

本日はここまでにします!
このままでは離れていない部分に全くひびがはいっていないのでちょっと味気ないですね。
次回は部分的にひび割れを追加していきましょう!