2012年2月22日水曜日

ThinkingParticlesでオブジェクト同士の設置箇所からパーティクルを出す方法。

なかなか手が動かず、久々の更新になってしまいました…。

今回はオブジェクト同士の設置面からパーティクルを発生させる方法です。
作例は船の航跡をイメージして作っています。
航跡のほか波打ち際などにパーティクルを発生させたい時の参考になれば。

TP FoamTest from take-imazu on Vimeo.



■元となるシーンはティーポットがパスに沿ってアニメーションして水面を進んでいるようなシチュエーションです。


■まずベースとなるオブジェクトにパーティクルを配置します。
①パーティクルの発生源となるベースとなるオブジェクトをTP内で扱いやすくするため、パーティクル化します。

ObjToParticleオペレーターでティーポットをパーティクル化します。グループはNodeobjグループです。

②ベースオブジェクトからパーティクルを発生させるための種となるパーティクルを作成します。

PositionBornオペレーターで数が50速度0のパーティクルを作っています。グループはSeedグループです。
発生させたパーティクルはこの時点では速度も無いのですべてのパーティクルが原点にある状態です。

③ベースオブジェクトをパーティクル化した物(Nodeobj)の表面に種(Seed)となるパーティクルを配置します。

PPassABオペレータのグループAにNodeobjをグループBのSeedを指定します。
SurfacePosヘルパーとPositionオペレータを使ってNodeobjにSeedを配置します。


■配置したパーティクルを水面より上と下でグループを分けます。
④水面オブジェクトの内側にあるパーティクルはUnderグループ、外にあるのはOverグループとして切り分けます。

SeedグループをInMeshコンディションオペレータとNodeヘルパーを使いグループを切り分けます。
InMeshのノードはノードヘルパーでwaterオブジェクトを指定、パーティクルがMeshの中に入ってonになったときUnderグループに送られ、Invertヘルパーを間に挟んでoffになった時はOverグループに送られようにします。
こうすることによってオブジェクトが水面で上下してもきちんとグループを切り替えてくれます。


■分けたグループを元にPPassABを使って間のパーティクルを抽出します。
⑤PPassABで先ほど切り分けたUnderグループとOverグループを指定して、Distansでグループ同士の距離を指定、その距離内にあるパーティクルをMidグループに送ります。

PPassABのアウトプットでどちらのグループに繋ぐかでどちらのパーティクルから抽出するか決めることが出来ます。両方をつなぐこともできます。
今回は水面より上のパーティクルを抽出したいのでグループAで指定したOverグループからパーティクルを抽出し、グループオペレータに送ります。
送られたパーティクルはmidグループになります。(説明が難しい…)


■抽出したパーティクルからアニメションさせるためのパーティクルを発生させます。
⑥midグループはまだ抽出しただけなので、ティーポットに張り付いたままです。
このmidグループから新たなパーティクルを発生させます。

midグループにPositionBornを繋いで新たなパーティクルを発生させます。
グループはSpawnとします。

■新たに発生したパーティクルをダイナミクスを与えます。
⑦重力を与えます。

SpawnグループにForceオペレータとPoint3ヘルパーを使って重力を与えます。
この方法は皆さんよく使われているようです。

⑧水面に当たったパーティクルが水面を沿うようにします。
また、水面にうまく当たらず下に落ちていくパーティクルが発生してしまったので、下に落ちていくパーティクルを消すため、水面に当たったパーティクルを新たなグループに送ります。

UDeflecterオペーレーターとNodeヘルパー、SurfaceFollowオペレータで水面オブジェクトにパーティクルが当たったら、水面オブジェクトに沿うようにしています。
水面に当たったパーティクルをグループオペレーターでFoamグループに送ります。

■余分なパーティクルを削除します。
水面にうまく当たらず水面より下に落下するパーティクルが出来てしまったのでそれらを消します。

⑨Spawnグループで水面より下に入ったグループをInMeshコンディションで水面オブジェクトを指定、onになったSpawnパーティクルをParticleDieオペレータで削除しています。


もっと早い段階で余分なパーティクルを消すことが出来ればもっと効率的になるのですが、うまいやり方が出来ませんでした…。


いつも思うのはこの先の段階のパーティクルの振る舞いをコントロールするのが本当に難しいですね…。