0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Houdini】初心者向け プロシージャルモデリング 階段

0
Posted at

はじめに

今回は、この動画のような階段を作る方法を、数学の誘導問題を解くように、一つひとつ設問をクリアしながら解説していきます。

また、試作を作る過程で今回多用する Match Size SOP の使い方についても紹介します。

この記事で学べること

この記事では次の内容を学べます。

  • Match Size SOP の基本的な使い方
  • Piece Attribute を使った Copy to Points
  • Poly Bridge を利用した階段の作成
  • For-Each Block を使った繰り返し処理
  • 試作からプロシージャルへ落とし込む考え方

このhipファイルのダウンロードは以下です

マイビデオ-1.gif

1. 試作

image.png

まずは、階段を作るために必要な要素を整理するため、プロシージャル化する前に手作業で試作を作成します。

こうすることで、「何をパラメータ化すればよいのか」「どのような処理が必要なのか」が明確になります。

今回は、この試作の中で Match Size SOP を何度も使用するため、まずは基本的な使い方を説明します。


Match Size SOPの使い方

1. 原点からのオフセット

Mayaで例えると、オブジェクトを任意の位置へ移動したあとに トランスフォームをフリーズし、その状態で トランスフォームをリセットする操作に近い考え方です。

Mayaでいうトランスフォームのフリーズと完全に同じ処理ではありませんが、ジオメトリのバウンディングボックスを基準に、位置や大きさを揃えるという点では近い感覚で使用できます。

まず、Matching の設定を以下のようにします。

image.png

すると、ジオメトリ全体が移動し、Z軸方向の最小値が原点(Z = 0) に揃います。

image.png

さらに Offset By に値を入力すると、原点を基準に任意の距離だけオフセットできます。

image.png

このように Match Size SOP を使うことで、ジオメトリの基準位置を簡単に揃えたり、一定量だけ移動させたりできます。階段のように複数のパーツを正確に積み重ねる処理では、非常に便利なノードです。

2. 第二入力のジオメトリに位置と大きさを合わせる

第二入力にジオメトリを接続し、Translate をオンのまま Scale to Fit をオンにします。

image.png

すると、第一入力のジオメトリを、第二入力のバウンディングボックスに合わせて移動・スケールできます。

Uniform Scaleの設定によって、アスペクト比を維持するか、各軸を個別に合わせるかを変更できます。

image.png

今回は画像は省略しますが、Uniform Scale を使用すると、任意の軸のみを基準にスケールを合わせることもできます。

Match Size SOP は、プロシージャルモデリングでは使用頻度の高いノードなので、この機会に使い方を覚えておくと便利です。


試作から読み取れること

では、試作した階段をもう一度見てみましょう。

image.png

配置を観察すると、それぞれの軸には次のような役割があることが分かります。

  • Z軸:原点を基準とした、階段の前後方向へのオフセット
  • Y軸:各階の高さ
  • X軸:Gridの幅

このように、一度試作しておくことで、オブジェクトをどのようなルールで配置すればよいのかが見えてきます。

また、階段同士をつなぐ部分は Poly Bridge SOP で作成できそうです。

さらに、試作から次のような構成にすればプロシージャル化しやすそうだと分かります。

  1. Poly Bridge SOP で階段全体の大きさと各段の配置を決める
  2. Box SOP を繰り返し生成する
  3. Match Size SOP で各Boxの位置と大きさを合わせる

このように試作を行う目的は、単に完成形を作ることではありません。

どのノードにどの役割を持たせるかを整理し、プロシージャル化の方針を決めることが重要です。

設問

ここからは、試作で整理した内容をもとに、プロシージャルに階段を作成していきます。

完成形をそのまま作るのではなく、数学の誘導問題のように、一つずつ課題をクリアしながら完成を目指します。


設問1. 奇数階と偶数階に分けてGridを複製してください

まずは、階段の土台となる GridCopy to Points SOP を使って複製します。

このとき、後の処理を簡単にするため、奇数階偶数階で分けて作成してください。


設問2. Poly Bridge用のEdge Groupを設定してください

複製したGridに対して、Poly Bridge SOP で接続できるように Edge Group を設定してください。

どの辺同士を接続すればスロープになるのかを考えながら設定してみましょう。


設問3. Poly Bridgeで作成したスロープを階段に置き換えてください

Poly Bridge SOP によって作成されたスロープを、試作で確認した方法を参考にしながら階段へ置き換えてください。

ポイントは、

  • Box SOP を繰り返し生成すること
  • Match Size SOP を利用して位置と大きさを合わせること

です。


設問4. 作成した要素をMergeしてください

最後に、

  • 階段
  • スロープ
  • その他作成したジオメトリ

Merge SOP でまとめ、完成させてください。

解答例

ノード構造については、冒頭で紹介したhipファイルを参考にしてください。

ここでは コードの詳細やノードのオプションについて説明します。

設問1

image.png

VEX

// Run Over: Detail

float height = detail(0, "height", 0);
float length = detail(0, "length", 0);

int iteration = chi("iterations");

for (int i = 0; i < iteration; i++)
{
    // 基本となるポイント位置
    vector pos = set(0,height * i,length / 2);

    string floor_type;

    // 偶数階
    if (i % 2 == 0)
    {
        floor_type = "even";
    }
    // 奇数階
    else
    {
        pos.z *= -1;
        floor_type = "odd";
    }

    // ポイントを追加し、追加されたポイント番号を取得
    int pt = addpoint(0, pos);

    // 偶数階・奇数階を識別するnameアトリビュートを設定
    setpointattrib(0,"name",pt,floor_type);
}

このVEXコードの目的

このコードは、階段を配置するためのポイントをY軸方向へ並べながら、Z軸の正負を交互に切り替えて配置する処理です。
結果として、ポイントは次のように配置されます。
i = 0 → Z軸のプラス側
i = 1 → Z軸のマイナス側
i = 2 → Z軸のプラス側
i = 3 → Z軸のマイナス側
同時に、それぞれのポイントへ次の文字列アトリビュートを設定しています。
偶数番目のポイント → name = "even"
奇数番目のポイント → name = "odd"

処理の流れ

heightとlengthを取得

繰り返し回数を取得

階数に応じてY座標を上げる

偶数・奇数を判定

奇数の場合はZ座標を反転

ポイントを追加

nameアトリビュートにevenまたはoddを設定

設問2

image.png

Copy to points のPiece Attribute とPack and Instance

Piece Attribute を使うことで
ターゲットポイントにつけたpointクラスのnameと
コピーするジオメトリのprimクラスのnameとで対応させてコピーができます。

これにより
奇数用のprimを奇数用のpointにコピーします。

注意点として
Poly Bridge SOP用の
primのEdge groupをコピーする際には
Pack and InstanceをオンにしてからUnpackをして展開することで
Edge groupのコピーができるということです。

またその際に手前用と奥用とでBridgeするEdgeをわけるために frontとbackのgroupを分けています

設問3

image.png

Poly Bridgeで作成したスロープの役割

ここでは、Poly Bridge SOPで作成したスロープを、そのまま最終形状として使用するわけではありません。

スロープは、主に次の2つの情報を取得するための基準として使用します。

  • Match Size SOP で各階段の位置と大きさを合わせるための寸法
  • PolySplit SOP で中央に追加したポイントから得られる、各段の配置位置

つまり、Poly Bridge SOPで階段全体の傾斜と寸法を決め、その情報を使ってBoxを階段へ置き換えています。

For-Each Block内でのMatch Size SOP

Poly Bridge SOPで作成したスロープに対して、PolySplit SOPで中央にエッジを追加します。

その後、Blast SOPを使って必要なポイントだけを残し、Copy to Points SOPで使用するターゲットポイントへ変換します。

最後に、For-Each Block内でBox SOPを作成し、Match Size SOPを使って各段の位置と大きさを合わせます。

image.png

その際にターゲットポイントの順番をSortで整えてから
最後の段の調整をしています

この記事では、処理を理解しやすくするために、front と back の階段を別々に作成しています。

  • front 用の階段
  • back 用の階段

ただし、片側の階段だけを作成し、
回転・移動して反対側へ配置する方法でも問題ありません。

より効率的な構成にしたい場合は、片側の処理を共通化するとよいでしょう。

設問4

image.png

最後に、作成したすべての要素を Merge SOP で結合します。

Merge後は、次の処理を行ってジオメトリを整理します。

  • 重複しているポイントを結合する

  • 不要なアトリビュートを削除する

  • 不要なグループを削除する

  • 法線を再計算する

まとめ

今回は、折り返しのある階段を題材に、試作からプロシージャル化までの流れを解説しました。

今回のポイントは、最初から複雑なノードネットワークを組み始めるのではなく、まず完成形を試作し、そこから必要な規則を読み取ることです。

今回の処理は、大きく次の4つのステップに分けられます。

  1. 奇数階と偶数階に分けてGridを配置する
  2. Edge Group を設定し、Poly Bridge SOP で各階を接続する
  3. 作成したスロープを基準として、Box SOP を階段へ置き換える
  4. すべての要素を結合し、ジオメトリを整理する

今回使用した主なノード

Match Size SOP

  • ジオメトリの位置や大きさを、別のジオメトリに合わせる

Copy to Points SOP

  • ポイントを基準としてジオメトリを複製する

Piece Attribute

  • アトリビュートの値に応じて、コピーするジオメトリを切り替える

Poly Bridge SOP

  • Edge Group同士を接続し、スロープを作成する

For-Each Block

  • スロープを1つずつ処理し、階段へ置き換える

Sort SOP

  • ポイント番号を並べ替え、処理順を安定させる

プロシージャル化の考え方

今回のような形状は、次のような手順で考えるとプロシージャル化しやすくなります。

完成形を観察する
        ↓
配置や形状の規則を見つける
        ↓
必要な処理へ分解する
        ↓
各処理をノードへ置き換える

完成形をそのまま再現しようとするのではなく、「どのようなルールで形状が構成されているのか」 を考えることが重要です。

プロシージャルモデリングでは、こうした考え方を身につけることで、今回の階段だけでなく、さまざまな形状にも応用できるようになります。

今回の題材は階段でしたが、同じ考え方は次のような形状にも応用できます。

  • 手すり
  • 建物
  • 配管

どの形状でも、完成形を観察し、そこから規則を見つけるという基本的な考え方は変わりません。

ぜひ、ほかの形状でも試してみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?