| On this page |
以下のスクリプトは、風による砂の輸送をシミュレーションし、より複雑なVEXスクリプトの例です。 このスクリプトの仕組みはあくまで近似であり、物理的な背景があるわけではありません。 しかしながら、調整可能なパラメータを用いることで、良好な結果を得ることができます。 また、高度な数値計算手法を用いなくてもアイデアを実現できることを示しています。
地形 ¶
地形セットアップには、景観のサイズと解像度を定義するHeightField SOPが必要です。
表面のディテールを高めるために、 Grid Spacing パラメータを
1に設定します。
山や地形構造を追加するために、HeightField Noise SOPを追加して、 1番目 の入力をそのHeightField SOPの出力に接続します。
このHeightField Noise SOPは、ほとんどデフォルト設定のままで構いません。
変更が必要なのは Amplitude パラメータだけです。
これを300に変更すると、地形が平坦化されて極端な高低差が回避されます。
ソルバ ¶
シミュレーションはSolver SOP内で実行されます。
このノードは非常に便利で、複雑な時間ステップ計算や安定性の問題を扱う必要がありません。
VEXコードを追加する だけ で、ソルバが残りの処理を実行してくれます。
-
Solver SOPを配置して、 1番目 の入力をそのHeightField Noise SOPの出力に接続します。
-
そのSolver SOPをダブルクリックして中に入ります。 そこで
HeightField Wrangle SOPを追加して、 1番目 の入力を
Pre Frameノードの出力に、そのOUTノードの入力をHeightField Wrangle SOPの出力に接続します。
Tip
Height Fieldネットワークの最後にHeightField Distort by Noise SOPを追加すると良いでしょう。
これによって、規則的なパターンが崩れて、平坦化された地形に構造を加えることができます。
50フレーム後の、補助ノードなしの侵食された地形
コード ¶
以下のVEXコードにはソルバの機能が含まれています。
各関数を個別に説明しませんが、そのスクリプトのコメント欄に情報を載せています。
//文字列はコメントを示します。
⌃ Ctrl + Cで以下のコードをコピーします。
⌃ Ctrl + Vで、そのスクリプトをそのHeightField Wrangle SOPの VEXpression フィールドにペーストします。
このプログラムには6つのカスタムパラメータ定義が含まれています。
これらのカスタムパラメータをそのHeightField Wrangle SOPのUI上に追加するために、
Creates sparse parameter for each unique call of ch() ボタンをクリックします。
// カスタムパラメータを定義します。 float base_angle_deg = chf("wind_angle"); float variation_pos_deg = chf("angle_variation_pos"); float variation_neg_deg = chf("angle_variation_neg"); float turbulence_strength = chf("turbulence_strength"); float wind_strength = chf("wind_strength"); float wind_shear_factor = chf("wind_shear_factor"); // 風向を差異ありで計算します。 // この部分では、角度の度単位をラジアンに変換します。 // オフセットは、時間、位置、任意のベクトルからランダム値を算出します。 // そして、その結果をvariation_neg_degからvariation_pos_degまでの範囲に再マッピングします。 // 最終的な風向を得るために、それらの値を加算します。 float base_angle_rad = radians(base_angle_deg + 180.0); float angle_offset = fit01(rand(@Time + dot(@P, set(12.345, 67.89, 0))), -variation_neg_deg, variation_pos_deg); float final_angle = base_angle_rad + radians(angle_offset); // 乱流を含むメインの風ベクトル。 // final_angleのサイン値とコサイン値を組み合わせてベクトルを作成します。 // curlnoise関数は、その風に微小な乱流を加えます。 // 3つのベクトルのwind_dir_base、wind_turbulence、turbulence_strengthは、風速ではなく風向を取得するために正規化します。 vector wind_dir_base = set(cos(final_angle), 0.0, sin(final_angle)); vector wind_turbulence = curlnoise(@P * 0.1 + @Time); vector wind_dir = normalize(wind_dir_base + wind_turbulence * turbulence_strength); // Wind Shear(ウィンドシア:風向や風速が急激に変化する現象)。 // ウィンドシアは、XZ平面において90度の時計回りの回転をします。 // ウィンドシアの強度は、wind_strengthとwind_shear_factorの積です。 vector cross_wind_dir = normalize(set(-wind_dir.z, 0.0, wind_dir.x)); float cross_strength = wind_strength * wind_shear_factor; // target_posは、現在のボクセルの砂の目標位置を決めます。 vector target_pos = @P + wind_dir * wind_strength + cross_wind_dir * cross_strength; // 確率係数。 // よりランダムな外観を得るために、このスクリプトは、ボクセル毎に輸送確率を計算します。 float prob_factor = fit01(rand(@Time + dot(@P, wind_dir)), 0.5, 1.0); float transport_prob = wind_strength * prob_factor; // この部分では、目標位置と現在のボクセル位置での地形の高さ値をサンプリングします。 float target_height = volumesample(0, "height", target_pos); float current_height = volumesample(0, "height", @P); // 現在のボクセルにおける地形の高さを設定します。 // このスクリプトは、ボクセルの砂が前のサンプルと計算に基づいて移動するかどうかを確認します。 // 砂が移動すれば、このスクリプトは、その砂を除去するか累積するか決めます。 // 砂が除去される場合、その砂の量が直接、地形の実際の高さに変換されます。 if (current_height > target_height) { if (rand(@P + @Time) < transport_prob) { float sand_amount = current_height - target_height; if (sand_amount > 0.0) { current_height -= sand_amount; target_height += sand_amount; @height = current_height; } } }
パラメータ ¶
このスクリプトには、環境条件をカスタマイズするためのパラメータがいくつか用意されています。
| パラメータ | 説明 |
|---|---|
| Wind Angle |
風向(単位は度)。0の値は、風が西から東へ吹くことを意味します。90度では、風向は真北から真南となります。
|
| Angel Variation Pos | 風向の プラス のバリエーション量(単位は度)。値が高いほどバリエーションが大きくなります。この値は Wind Angle に加算されます。 |
| Angel Variation Neg | 風向の マイナス のバリエーション量(単位は度)。値が高いほどバリエーションが大きくなります。この値は Wind Angle から 減算 されます。 |
| Turbulence Strength |
風の乱流の強度。設定値が高いと不要なアーティファクトが生じる可能性があります。初期値は0.3程度から始めてください。
|
| Wind Strength |
風速。このパラメータには単位がなく、単なる無次元係数です。値が高いほど砂の輸送が加速されます。適切な値の範囲は0.3から0.9ですが、より高い設定でも機能します。
|
| Wind Shear Factor |
このスクリプトは、調整後の Wind Angle に垂直なウィンドシアも適用します。最終値はWind Strength * Wind Shear Factorとして計算されます。
|
パラメータ調整後、プレイバーに移動して、 Play ボタンをクリックしてシミュレーションを開始してください。
このスクリプトの実行速度は比較的速く、ほとんどの場合50~70フレーム以上のシミュレーションは必要ありません。