で、そんなことをしているうちにコリジョンオブジェクトが上手く機能しなくなったり。 ある程度シーン作成が進んでから、整理をしようとして名前とかちゃんと付け始めるのですが、コリジョンオブジェクトを入れた Group の名前を変えたり、他の Model の下にぶら下げたりなどしているうちに、なぜだか ICE ツリーから認識されない状態になってしまったというか、コリジョンが突き抜けてしまうようになってしまったというか。 まったくもう。
タービュランスのツリーですが、Turbulize とか Randomize を by Range でやりたい場合、かつ 0 を中心にプラスマイナスを同じ幅でやりたい場合に、俺はこういうツリーを組むことが多いです。 なんのことはない、Min Value と Max Value にプラマイ違いの同じ数値を2回打つのがめんどくさいというだけです。 パーティクルの挙動に関わる話ではなく、2回の数値入力を1回で済ませたいという、ほんとそれだけです。
なのであまり調整の必要がない場合はこのツリーも組みません。 っていうか、最初はこのツリーを組まないまま調整を始めて、Min Value と Max Value を数回打ち直すハメになった時点で超めんどくさがりの俺はキレ始めて、このツリーを組んでしまいます。 そして組んだ後に最初に入力した数値がいい具合だったのでそれで確定してしまい、何度も数値を打ち直すのを便利にするためにわざわざ組んだこのツリーが、たった1回の入力でその役目終了という結果になることが多いです orz
これも前回まで出てきたのと同じ。Ray Length を使って、カメラから出たレイとパーティクルのサーフェスの交差した座標におけるカメラからの距離をゲットし、デプスの範囲を Change Range で決めて 0 ~ 1 の範囲にリマッピングし、それを色に変換するから白黒のグラデになる。というものです。
しかも、こともあろうに透明度を考慮していない。 パーティクルのエッジが透明であるにも関わらず、おかまいなしに Ray Length を使っている。 Ray Length はプライマリレイの長さですからね。 つまり透けたサーフェスを通過した時点でそこから先はセカンダリレイになるわけで、返してくる値はカメラのポジションからの距離ではなく、おそらくプライマリレイがヒットした座標(つまり透けたサーフェスの表面)から次のサーフェスの交点までの距離を返してくるはずだと思います。
Aの部分ですが、Get Particle State ID でパーティクル1粒1粒の State ID を取得し、それが 2 とイコールだったら IsThisFuckinTrail という独自アトリビュートに true をセットしています。
これは後ほど説明しますが、RenderTree 上で、メインの花火の光球(つまり先頭弾=上記の State 1 のパーティクル)とトレイルで違う質感を持たせたかったからこうしています。 先頭弾なのかトレイルなのかは、State ID を取得すればわかるじゃないですか。 このトレイルの State ID は2なんだから、2とイコールならそのパーティクルはトレイルであると判断できます。 そしてその結果を元に、RenderTree 上で分岐させています。
Value を見ると、-0.065 から -0.015 の値を加算してますね。最小も最大もマイナスの値です。つまり、元の Value の値にマイナスの値を足してやることによって、より小さい数値にするということです。マイナスを加算しているわけだから、減算(引き算)をしているのと同じことですね。 結果、Value(明度) の値が小さくなるということは、色が暗くなるということです。
こうして元のパーティクルの色から、色相を少し変え、明度を少し下げた色が、再度 HSVAtoColor で Color 情報に変換され、B1の Set Particle Color でセットし直されます。
その接続先が大事なわけですが、Execute ノードのポートに入り、最終的には State2 の Execute Every Frame ポートに入っていってますね。つまり、上記の一連の色操作は、毎フレーム行われるということです。
次のフレームでは、また B2 の Get Particle Color から始まるわけですが、そこで取得される色は、前のフレームで一度この処理を通った色なわけです。 なので、生まれた最初の色から計算をし直すのではなく、色相をちょっとずらして明度をちょっと下げた結果の色が再び同じ処理にかかるわけなので、そしてランダムの範囲が狭いため、前のフレームからある程度連続性のある色になります。 前のフレームと比べて急にとんでもなく違う色になったり、急にズドンと暗くなったりはしないということです。
B1の Set Particle Color を、Execute Once on Enter State ポートに繋ぎ直しました。もともとは Execute Every Frame に入っていたので、毎フレ計算されていたわけですが、Execute Once on Enter State ポートにつなぐということは、この State に突入した瞬間に1回だけ計算されて、以降は値が変わらないということになります。
あと、結果が分かりやすく出るように Value のランダムに Multiply by Scalar を挟んで、ランダムの振れ幅を3倍だか4倍に拡大しています。 これは視覚的に分かりやすくしたというだけで、今説明しようとしている「接続先で結果が違う」という話とは本質的に関係はありません。
上の ICETree画像を見るとわかるように、Turbulize Mesh で発生させたタービュランスパターンは Y のみに適用されています。つまり PointPositon の Y 方向だけの変異量として使っています。 その上で、 X と Z でメッシュの分割数が違えば、この Y の変異量への敏感さというか、メッシュ解像度による追随性に差を付けられるので、結果的に上記の「引き延ばした」ような効果になります。
ICETree では、Get Particle State ID を使って State を取得し、2だったらそれはトレイルだから IsThisFuckinTrail を true にする、なんていうめんどくさいことをやっていますが、RenderTree から直接 Particle State ID を取得することもできるので、そのやり方にすれば IsThisFuckinTrail なんていう下品なカスタムアトリビュートは不要になり、ICETree はよりシンプルになり得ます。
しかし RenderTree には if ノードなどの直感的に扱える便利な条件分岐のノードがないため、今回の場合は 0, 1, 2 の3種類の値をとり得る State ID を RenderTree 上で取得しても、その後の分岐を作るのがめんどくさいです。っていうかわかりにくいです。
Scalar_State で Ray Length を拾っています。Ray Length = レイの長さってのはつまり、カメラからの距離です。 正確に言えば、カメラから発射された Primary Ray がジオメトリと交差した地点( Intersection Point )における、そのレイの長さということになると思います。 ともかく、この方法でカメラからの距離が、オブジェクト単位ではなく、ピクセル単位でゲットできます。Primary Ray 専用ということになるので透明のブツを透過した距離には使えませんが。
こうして得られた距離を Scalar Change Rance にブチ込んでいますね。そして Old Range Start が 100 で Old Range End が 0 になっていますから、Ray Length の結果を、100 から 0 のレンジだと見なしていることになります。 そしてそのレンジを New Range の Start と End で 0 から 1 にリマッピングしたスカラ値を吐き出しています。 結果、オブジェクト表面の、カメラから距離が 100 の部分は 0 で、距離が 0 の部分は 1 になります。
この 0 から 1 のスカラ値を Scalar to Color でそのままカラーに変換してやれば、0 = 黒、1 = 白というグラデーションができあがり、普通にリニアなデプス画像になります。 が、今回の場合は、Gradient Mixer のインプットにブチ込んで、グラデーションを調節していますね。黒のレンジを圧倒的に大きくしています。
タービュランスの方は、既に Turbulize Around Value で決定済みのタービュランスの強さに対して、Multiply By Scalar を使って何倍にするかを決める Factor につながっています。なので、生まれてすぐは 0 を掛け算するからタービュランスの力はゼロ、死ぬときは 1 を掛け算するからタービュランスの力は Turbulize Around Value で決定済みの強さとイコールになります。
ってことでこのコンパウンドの中身を見てみると、 なんのことはない、Turbulize Around Value を使っているだけではありませんか。
Base Value に Get Particle Velocity から得られたベクタがブチ込まれていますね。つまり、前のフレームでパーティクルが飛んでいた方向を新たなタービュランスの基準点にしているということですね。こうしないと連続性のない、1フレごとに位置が不規則に変わったりする、デタラメなランダムになりますもんね。
まあともかく、フォースとして Turbulize Around Value を与え、Variance に XYZ を同一の値で与えた時と同じ挙動になるんではないかと思います。誰か実験して教えて下さい。 同じなのであれば、フォースの方でやるよりこっちが楽なような気もするし、そうでもない気もするし、どうでしょう。 まあどっちでもいいけど。
こんなところでしょうかね。
前回の c02 に無かった要素としては、メインの光球の寿命が尽きるときにもう1回小さい花が咲くというものですが、Spawn on Trigger 使ってるだけだし、全球状に広がってその後落ちていくだけだし、さほど工夫した感じがありません。 この花にもトレイルを付けたり、この花を構成する玉の寿命が尽きるときにもまた新しい花を咲かせたりなどと、永久ループな花火にするのも手かもしれません。フラクタル相似的花火。いつかやってみよう。
あ、あと、今回は State Machine ノードを使いませんでした。 クリックするとでかい画像。
Simulation Root ノードってのは、たしか 2011 SAP から付いたんだっけ。 この Simulation Root ノードに、State Machine の機能があるんですよね。 チェックボックスをオンにすると、Simulation Root 内のポートが State Machine の働きをするようです。
でもなんだかわかりにくいというか、State Machine を State のルートにして、そこから枝分かれさせた方が好きです。 今回は、このつなぎ方でもいいのかどうか試してみただけという。
このカットの場合、Lenscare に含まれている Depth of Field エフェクトを使ってますね。デプス素材を指定し、ピントを合わせたい部分をピックすると、ピック部分の輝度を合焦点の距離にしたボケを生成してくれます。
奥行きに関係なくレイヤ全体をレンズボケにしたい場合は、Depth of Field ではなく Out of Focus エフェクトを使います。デプスの計算をしない分、たぶんこっちの方が速い。他のカットでたぶん使ったと思う。 パラメータは、デプス関係が無いだけで、ほぼ Depth of Field と同じ。
ちなみにまた質問ですが、 Point のままレンダリングってちゃんとできるんでしょうか? ここがわかっとらんのです俺。 ほんとは Point = つまりただの「点」あるいは「光点」としてレンダしたかったりするんですけどね。 しかし Shape が Point の状態で、パーティクルサイズを少しでかくしてレンダしてみると、下半分の半円みたいな形でレンダされますよね・・・・? ここら辺研究せねば・・・レガシーパーティクルはこの辺楽だったなあ。 っていうか、最も基礎的な研究を怠ったまま花火などを作ろうとしている己の傲慢さに腹が立ちますええ立ちますとも。
・State
Dは State ですね。このエミッションで生まれるパーティクルの State ID は 0 ですと言っているだけです。が、この後 Spawn Trails とかやるので、今自分がいじくっているパーティクルの State ID はいくつだ、と意識しておかないわけにはいきません。っていうか今回の花火プロジェクトは、1つの State だけで作れる花火は少ないので、常にそれを意識しながらやっていました。
で、サイコロの結果によって、3種類の Modify Particle Color を突っ込んでいます。PPG は表示していませんが、この3つの Modify Particle Color は、いずれも寿命に応じてパーティクルの色がグラデーションで変化するようにしてあります。そのグラデの色を3つで微妙に変えてあります。
光球1個生まれるごとにサイコロを振って、その結果でトレイルの有無を決めるというこのシステム、ちゃんと正しく動いているかどうか一応確認してみました。サイコロが出した値を round した後の整数と、結果である true/false を Show Value で表示させ、見やすくするためにエミッションの数を減らしました。
ちなみにこの画像を見ると、どうやら、メイン光玉だけではなくトレイルの方のパーティクルに対してもこの SpawnFlag の評価がされているように見えますね。0,0 と表示されているから。 たぶん無駄だと思います。メインの光玉に対してトレイルを持たせるかどうかのフラグなんだから、結果として出てきたトレイルのパーティクルがこのフラグを持つ意味はありません。この計算をさせなくすることができればシミュレーションが速くなる気がするのですが、どうでしょう。あるいは Show Value のために出てきただけであって、実際は計算されてないなんてことはあり得るかしら。
最近のコメント