Houdini 20.0 コピーとインスタンス

For-Eachコピーチュートリアル

On this page

概要

Copy to Pointsを使用する際に、各コピーのジオメトリにバリエーションを加えたい時があります。 ターゲットポイント上のPointアトリビュートを使ってFor-Eachループ内のコピー生成に影響を与えることで、バリエーションを加えることができます。 詳細は、コピーにバリエーションを加える方法を参照してください。

このチュートリアルでは、ランダムな星のボールを作成します。このエフェクトを実装するには:

  • 星形を示したアトリビュートが付いたターゲットポイントを作成します。

  • For-Eachループ内で、球のポイント上にプロシージャルな星形をコピーします。

  • pointエクスプレッションを使って、そのターゲットポイント上のアトリビュートに基づいて、その星形を可変させます。

ソースポイントの作成

  1. シェルフの Create タブにある Sphere⌃ Ctrlクリックして、球を原点に追加します。

    Createツールを⌃ Ctrlクリックすることで、即座にオブジェクトを原点に作成することができます。 ⌃ Ctrlを使わずにアイコンをクリックすると、Houdiniは、あなたがその新しいオブジェクトの位置を指定するまで待ちます。

  2. オペレータコントロールツールバー(3Dビューの上にあります)で、 Primitive TypePolygon に、 Uniform Scale0.6に設定します。

  3. ネットワークエディタで、sphere_objectノードの名前のところをクリックして、その名前をstarballに変更します。

  4. そのstarballノードをダブルクリックして、そのジオメトリネットワークの中に入ります。

  5. Attribute Createノードを作成し、そのノードをsphereノードに接続します。

  6. Attribute Createノードのパラメータエディタで:

    • Namedivisionsに設定します。

    • Class を“Point”に設定します。

    • Type を“Integer”に設定します。

    • 1番目の Value フィールドに以下のエクスプレッションを設定します:

      int(rand($PT) * 6) * 2 + 8
      

      これによって、球のポイント上にdivisionsPointアトリビュートが作成されます。 このAttribute Createノードの$PTは現行ポイント番号です。このポイント番号をrand関数のシード値として使用することで、ポイント毎に異なる乱数を生成することができます。

      rand()の結果(0以上1未満)を6倍にして整数化することで、0から5までのランダムな整数を生成することができます。 さらにそれを2倍にすることで、0から10までの偶数の分割数を常に取得することができます。最低限の星の形のポイント数は8個なので、そこに8を追加して、8から18までの数を取得しています。

Tip

Geometry Spreadsheetを使用することで、ノード内のすべてのポイントのアトリビュート値を調べることができます。 ネットワークエディタ内のジオメトリノードを右クリックして、 Spreadsheet を選択します。

プロシージャルな星を作成する

  1. まだstarballジオメトリネットワークの中にいたまま、Circleノードを作成します。

  2. circleノードのパラメータエディタで、 Primitive TypePolygon に、 Radius0.2, 0.2に設定します。

ポリゴンの円を星形に変換するために、1つおきのポイントを含んだグループを作成し、そのグループをトランスフォームさせます。

  1. Group by Rangeノードを追加し、それをcircleノードに接続します。

    • Groupevenに設定します。

    • Group Type を“Points”に設定します。

    • “Range Filter”を Select 1 of 2 に設定します。

  2. Transformノードを追加し、それをgrouprangeに接続します。

    • 1つおきにポイントをトランスフォームさせたいので Groupevenに設定します。

    • Uniform Scale0.5に設定します。

  3. transformノードのディスプレイフラグをクリックします。

    circleノードを選択して、その Divisions フィールドに色々な値を入れてみることで、そのフィールドが星の形状にどのように影響するのかを確認することができます。 これは星のポイントで起こり得る表示の問題も対処することができます。

ポイントへのコピー

  1. Copy to Pointsノードを作成します。transformノード(星の形状)を1番目の入力に接続します。attribcreate(コピー先の球ポイント)を2番目の入力に接続します。

  2. copytopointsノードのディスプレイフラグをクリックします。

    ビューポートでは、そのノードは単に現在の星のジオメトリをそのまま各ポイント上にコピーしているのがわかります。 これがよく行なわれる使い方です。 とはいえ、このチュートリアルでは、球に作成されたdivisionsPointアトリビュートを使って、それぞれの星の分割数を制御したいと思います。 そのため、For-Eachループを使用します。

For-Eachループの追加

  1. ⇥ TabメニューからFor-Each Pointを作成します。

    Houdiniは、自動的にforeach_beginforeach_endのノードのペアを作成します。

  2. そのBeginノードとEndノードの間にノードを接続していくので、それらのノード間に空きスペースができるようにネットワークエディタ内で引き離します。

  3. foreach_endノードを選択します。 Iteration Method が“By Pieces or Points”に設定されていることを確認します。これが私たちの求めているメソッドです。要するに、このメソッドは入力内の各ポイントをループで処理します。

    いくつかのパラメータが以下の設定になっていることを確認します。

    • ブロックがポイントに対してループするように Piece Elements を“Points”に設定します。

    • ブロックがアトリビュートによるピースのグループ化をせずに個々のポイントすべてに対してループするように、 Piece Attribute を無効にします。

  4. attribcreateの出力(アトリビュートが追加されたコピー先のポイント)をforeach_beginノードに接続します。

    これは、(アトリビュートが追加された)球のポイントに対してループさせたいことをHoudiniに伝えます。

  5. 新しくCopy to Pointsノード(copytopoints2)を作成します。

    • transformノードの出力(星のジオメトリ)をcopytopoints21番目の入力 に接続します。

    • foreach_beginの出力をcopytopoints22番目の入力 に接続します。これは、各ポイントをループでCopy to Pointsノードに送ります。

    • copytopoints2の出力をforeach_endノードに接続します。

  6. foreach_endのディスプレイフラグをクリックします。

    再度、星がポイント上にコピーされますが、そこに問題があります。というのも、すべての星がその球の法線が使われずに同じ向きになっています!

    (法線とは、ポリゴンフェースの3Dの向きを示したベクトルのことです。)

    この理由は、For-Eachループは入力ジオメトリから1個ずつポイント のみ を抽出するので、その球にポイント法線がなかったからです。 そのため、コピーノードは、そのコピーを適切な向きにするのに必要な情報を持っていません。

  7. そのポイントの法線を修復するためにNormalノードを作成し、それをsphereノードとattribcreateノードの間のワイヤー上にドロップします。そのNormalノードのパラメータエディタで、 Add Normals to を“Points”に設定します。

    これは、球のポイント上に法線アトリビュートを作成します。これによって、その球のポイント法線によって、そのコピーの向きが変更されます。

それぞれの星にバリエーションを加える

この時点で、やっと本来のCopy to Pointsの出力を再現することができました!しかし、まだループによるコピーのセットアップが完了しただけです。これからコピー毎にジオメトリにバリエーションを加えていきます。

  1. circleノードを選択します。

  2. Divisions フィールドに以下のエクスプレッションを入力します:

    point("../foreach_begin1", 0, "divisions", 0)
    

    pointエクスプレッション関数は、以下の引数を受け取ります:

    point(path_to_geometry_node, point_number, attribute_name, index)
    
    • path_to_geometry_nodeはFor-Each Beginノードのパスです。コピー先となるポイントは、ループする度にこのパスに格納されていきます。

    • point_number常に0 です。その理由は、ループする度に1個のポイントしか操作しないからです。

    • attribute_nameは読み込みたいPointアトリビュートの名前です。

    • アトリビュートタイプがintegerまたはfloatであれば、index0のままにすることができます。アトリビュートタイプがコンポーネント(例えば、カラーならR, G, B、ベクトルなら3つの軸)であれば、index0, 1, 2などのように変更してpoint関数を個々にコールして、各コンポーネントを別々に読み込む必要があります。

  3. これで、処理されるポイントのPointアトリビュートを使って、ネットワークによるそのポイント上にコピーされるジオメトリの生成方法を制御できるようになりました。それぞれの星の形状は、その球にセットアップしたPointアトリビュートを使って、その星のコーナーの数を決定します。

    できました!

完成

Tip

For-Eachループは、コピーの数が多くなるほど遅くなってしまいます。コピーを高速化するには、そのループをコンパイルブロックで囲んでみてください。

コピーとインスタンス

はじめよう

次のステップ

導師レベル

古いワークフロー