斜方投射

INDEX

はじめに

こんにちは。モノリスソフト テクニカルアーティストの廣瀬です。
今回はHoudinを使い様々な方法で斜方投射(俗に言う、砲丸投げの軌道・スパークとか)を作ってみます。
この記事では、

  • POP
  • Solver
  • VEXを使用した簡単な数学的な手法

の3種類で作ってみます。

斜方投射というシンプルで基礎的な題材ですので、HoudiniのPOPがよくわからない方や、エフェクトアーティストの方の再学習などにお役立てください。

tech_38_01_02.jpg

サンプルファイル(monolithtech_solver.zip 43.4 KB)はこちらです。

DOWNLOAD

解説

ネットワーク上から見ていきます。

初期セットアップ

Point Generate SOP

任意の数のポイントを作成します。
今回はここで作成したポイントを使ってシミュレーションを行います。

tech_38_03.jpg

Attribute Randomize SOP

Point Generate SOPノードで作成したポイントに初速度のアトリビュートを作成します。
今回はY軸に対してコーン状の初速度を作成しています。
Attribute Nameの v はHoudiniでは慣例的に1秒の間に進む速度として扱われます。

tech_38_04.jpg

Transform SOP

Attribute Randomize SOPノードで作成した初速度を適当にトランスフォームしています。
トランスフォームと言われると位置移動のイメージがありますが、速度もこのノードでトランスフォームすることができます。
HoudiniではP, N, v, orient など慣例的に使用するアトリビュートにはアトリビュートタイプのメタデータが設定されていて、Transform SOPノードなどはこれらの情報を元に適切にトランスフォームを行ってくれます。もちろん、アトリビュートタイプメタデータはユーザーが新たに作成したアトリビュートにも設定することができ、Attribute Create SOPノードなどを使って指定することができます。

tech_38_05.jpg

これで初期セットアップは終わりです。
ここから先は様々な方法でシミュレーションをしてみます。

POP

まずは、POPを使用した方法です。
POPはHoudiniのパーティクルシミュレーションシステムです。

Switch SOP

POPでは毎フレームポイントが追加されてしまうので、このノードで開始フレーム以外はポイントをなくして毎フレームポイントを追加されなくしています。
他にも後述するDOP Network SOPノード内で、POP Source DOPノードのInpulse Activationパラメーターを設定したり、Enable Solver DOPノードやGas Intermittent Solve DOPノードを使用する方法などもあります。

tech_38_06.jpg

DOP Network SOPノードをダブルクリックしてDOP Networkに入ります。

POP Object DOP

パーティクルシミュレーションに必要なデータ構造を定義しています。

tech_38_07.jpg

POP Source DOP

パーティクルを毎フレーム追加しています。俗に言うエミッターです。
ここではDOP Network SOPノードの1番目の入力、つまりSwitch SOPノードのジオメトリ情報を取得してパーティクルとして追加しています。

tech_38_08.jpg

POP Solver DOP

パーティクルシミュレーションのソルバーです。速度や位置の更新、コリジョンなどが適応されます。
積分計算はオイラー法が採用されているようです。

tech_38_09.jpg

Gravity Force

パーティクルに重力を適応しています。

tech_38_10.jpg

Solver

続いて、Solverを使用した方法です。
Solverは自前の積分計算を作成できるノードです。

Solver SOPノードをダブルクリックして中に入ります。

tech_38_11.jpg

DOP Import SOP

前フレームのジオメトリ情報を取得しています。
ポイントに限らずライン・メッシュ・NURBS・ボリュームなどSOPジオメトリは何でも前フレームの情報を取得できます。

tech_38_12.jpg

Attribute Wrangle SOP

自前で積分計算を実装しています。
今回はPOPに合わせてオイラー法で実装しています。
@TimeInc は時間刻み幅 (Δt) です。これはFPSやサブステップなどを加味した適切な値が入っています。
@v はセットアップで作成していた速度アトリビュートのことです。重力を毎フレーム追加して上書きしています。
@P はポイントの位置です。速度を毎フレーム追加して上書きしています。

tech_38_13.jpg

VEX

最後に、VEXを使用した方法です。
斜方投射を数値的ではなく解析的に解いて、シミュレーションせずに位置と速度を算出しています。
よくよく見ると高校物理の内容のはずなので、それを思い出しならコードを読んでみてください。

float g = -9.80665;                        // 重力加速度(m/s^2)
float t = @Time;                           // 現在の時間(秒)
float vw0 = length(set(@v.x, @v.z));       // 横方向の初速 (m/s)
float vh0 = @v.y;                          // 縦方向の初速 (m/s)
float vw = vw0;                            // 時間tでの横方向の速度 (m/s)
float vh = (g * t) + vh0;                  // 時間tでの縦方向の速度 (m/s)
float pw = t * vw0;                        // 時間tでの横方向の位置 (m)
float ph = (0.5 * g * t * t) + (t * vh0);  // 時間tでの縦方向の位置 (m)
float x = @v.x / vw0;
float z = @v.z / vw0;
@v.x = vw * x;
@v.y = vh;
@v.z = vw * z;
@P.x = pw * x;
@P.y = ph;
@P.z = pw * z;

tech_38_14.jpg

結果

Merge SOPノードを表示すると各手法の結果を同時に見ることができます。
微妙に結果がずれているのは、数値解 (シミュレーション) と解析解のずれです。
エフェクトアーティストの方は、シミュレーションで円運動などを作ろうとしたときに、速度をちゃんと設定しているつもりなのに、円の軌道からずれていってしまった経験はありませんか?
それは、まさにこれが原因です。

tech_38_15.jpg

これはDOP Network SOPノードや Solver SOPノードのサブステップを上げると解析解に近づいていく様子を見ることができます。
サブステップをあげる以外の手法としては、1フレーム後の目的の位置に行くように速度を強制的に設定してしまうことです。以下のような計算です。

@v = (@Pnext frame - @Pcur frame) / @TimeInc;

この方法は、きれいな円運動を行いたいときなどに、著者もよく使用したりします。

tech_38_16.jpg tech_38_17.jpg

また、Trail SOPノードでポイントの軌道を見ることができます。

tech_38_18.jpg

最後に

今回は様々な方法で斜方投射を作成してみました。
一つの斜方投射をとっても、様々な方法で実装することができる柔軟性もHoudiniの魅力の一つです。
この記事が、HoudiniのPOPの理解や、エフェクトアーティストの方の再学習の手助けになりましたら幸いです。

執筆者:廣瀬

映像業界を経てモノリスソフトへ入社。 以来、テクニカルアーティストとして主にエフェクト関連の業務を担当。 好きな食べものはソフトクリーム。

ABOUT

モノリスソフト開発スタッフが日々取り組んでいる技術研究やノウハウをご紹介

RECRUIT採用情報