2012年1月27日金曜日

前回の記事の問題解決方法。

前回の記事で書いた問題が解決しましたのでその報告です。
前回の記事を読んで少しでも解決策を考えていただいた方、アドバイスをくれた方ありがとうございました。

では解説です。
まずどういったことがしたかったのかわかりづらかったようなので説明いたします。
■シチュエーションとして水面などからオブジェクトがでてオブジェクトの表面をパーティクルが沿って下に流れ落ちるという物を作りたかったのです。
(ムービーではオブジェクトの表面に沿っていませんが…)
■そして流れ落ちるパーティクルがどんどん減って行きたかったのです。
■また、データを軽くするため水面下にあるときはパーティクルを発生させたくありませんでした。

■念のためベースとなる仕組みの説明をします。
まず元となるシードのパーティクルを作ります。
オブジェクトの表面にパーティクルを配置し、アニメーションについて行くようにしています。
表面に発生させたパーティクルからスポーンを出しています。
スポーンとなるパーティクルが徐々に減るようにParticles/[s]の値をアニメーションさせています。
最後は重力でパーティクルが落ちるようにしています。
この状態だとまだパーティクルがZのゼロより下にあってもパーティクルが出てしまいます。

■パーティクルがZのゼロ以下にあるときはパーティクルを出したくなかったのでPoint3ノードThresholdノードを使いパーティクルがZより上に移動したときにPosition Bornノードがオンになるようにしてみました。
一見問題ないのですが、(テストシーンがわかりづらくてすみませんでした。)
本番のシーンではこのつなげ方だと、パーティクルが徐々に減るというよりぷつりと切れて出なくなる印象になってしまいました。

■そこで色々試したのですが、うまく行かず、とりあえず回避策としてシードから発生するパーティクルがZのゼロ以下にあるときは消すようにしていました。見た目上は問題ありません。
ただし、計算上は一度スポーンのパーティクルを発生させてからポジション判定をして消していたのでデータの無駄が多くなっています。
今回パーティクルを大量に出したかったのでだいぶデータのロスになります。

■そこで解決策です。
種となるseedグループが水面より下にいる場合にはseed_Bグループにデータを送ります。たったこれだけでした…w
ここで重要なのはseed_Bグループを元のパーティクルseedグループの子供にしてあげることです。
このseed_Bseedグループの並列の場所に作るとうまく行きませんでした。

出来てしまえばなんてこと無かったのですが、今回は簡単なはずだけど、出来そうでできない。
後ちょっとで出来そうなのにうまく行かないというもどかしさに陥りました。
まだまだちょっとした事でつまずいているので、早くこのレベルから脱出したいものです。






2012年1月23日月曜日

ThinkingParticlesでPositionBornのOnインプットにノードをつなげたときの挙動の違いについて

今回はTipではなくちょっと困った問題が起きたため、問題解決のための質問記事です。
(自分のブログで質問ってのも変な感じですが…)

■TPでPositionBornのOnインプットにノードを繋げたとき、パーティクルの挙動がよくない結果になってしまいました。

作例は
①Teapotに元となるパーティクル(Seed)グループを発生させる
②SeedのパーティクルがZの0(ゼロ)より上に来たときにPositionBornでSpawnとなるパーティクルがを発生させたい
③なおかつ時間経過によってSpawnのパーティクルを減らしたい場合です。

検証ムービーと画像です。




ここでちょっと問題が起こりました。
右のように組めば、一応らしくはなるのですが、Spawnのパーティクルの減り方が思うように減ってくれません。
急にぷつりと減ってしまう感じです。
理想は左のパーティクルのような減って行き方をしてほしいのです。

では、SpawnがZの0(ゼロ)より下に来たときに消せばよいのではないか?と思うのですが、それだとパーティクルを大量に発生したときにどうしても重くなってしまいます。

もし、この問題の解決方法をご存知の方がいましたらよろしくお願いいたします。
もちろん引き続き検証をしていきますので解決したら、また記事にしたいと思います。

以下にmaxファイルを置いておきますのでご興味ある方はダウンロードしてみてください。(max2012)
TP_positionborn_test.max

2012年1月22日日曜日

ParticleFlowにあるSplitAmountをTPで再現する方法

ParticleFlowにはある一定の条件によってパーティクルを別のイベントに送るオペレータ「SplitAmount」がありますが、これに似たようなことをTPで実現する方法です。

まず、元となったのはsky-high-nest-blogのけゑさんのこの記事です。
(ほとんどそのままパクっただけですがw)
「(TP Basic) Randomオペレーターを使ったビューポートのパーティクルを間引く方法」
けゑさんはのブログはCGやってる人なら一度は見たことあるであろう有名なブログです、いつも大変勉強になる記事ばかりで、ホント頭が下がります。
この記事も自分が質問した事をものすごく丁寧に解説してくれました。
改めてありがとうございます!
自分もけゑさんのような丁寧な記事が書けるよう精進します。

では本題にもどります。
今回は以下の二つの方法を書きたいと思います。

元のパーティクルはシンプルでPositionBornでパーティクルを発生しredグループからblueグループに送っているだけです。
■Randamにある割合でグループを分けるには。
redグループからRandomオペレータ(NewValueParはAnimationを指定)をつないでThresholdで割合を決めてblueグループに送っているだけです
ちょっと謎なのがThresholdで割合を指定しても、Randomオペレータのシード値によっては思った割合にならないことがありました。

■パーティクルIDの範囲でグループを分けるには。
こちらはもっと簡単でredグループからThresholdで送りたいIDの範囲をしていてblueグループにつなぐだけです。

他の条件も再現できたらまた書いていきたいとおもいます。

TPをしばらく触った方なら、「知ってるよ。常識だよ」って記事だとおもいますが、元々このブログでのTPの記事は簡単なことや初心者の方に向けての記事ですので温かい目で見守ってくださいw
(自分のTPの経験がまだ乏しいだけですが…。)
もっといい方法あるよ。や他の条件を再現できるよって方はコメントなどいただけるとうれしいです。

2012年1月14日土曜日

ThinkingParticlesをつかってアニメーションオブジェクトを差し替えてみる。

TPを使ってインタラクティブにオブジェクトを差し替える作例です。

自分がTPを覚えようとおもったのはこういったことが効率的に出来ればいいなとおもったのがきっかけだったりします。
といっても難しいことは何も無いのですが、いくつか発見があり、忘れないようにしなければならないことがあったので記事にしました。

まずはムービーを見てください。


TP_AnimReplaceTest from take-imazu on Vimeo.


では解説です。

◆ Planeに配置されたパーティクルに対してアニメーションされたオブジェクトを割り当てています。
(配置しているオブジェクトはPlaneの脇にあるオブジェクトです)
Sphereが通り過ぎると(今回はDistansを使ってます)アニメーションが変わっているのが解るとおもいます。
これはアニメーションが変わったというよりオブジェクトそのものを差し替えています。
よく見ていただくと、BoxやTeapotのポリゴン数が変わっています。


◆まずはGenerateダイナミクスです。
ここはごく普通にPlaneオブジェクトのサーフェイスにPositionBornでパーティクルを配置しています。
(NodeヘルパーでPlaneオブジェクトを指定、SurfacePosヘルパーでFaceを指定)


◆次にShapeA_Assignダイナミクスです。
ここもごく普通にGeomInstanceノードでパーティクルに対してシーン内のオブジェクト割り当てているだけです。


◆次はShape-A_to_Bダイナミクスです。
ここではShapeAグループのパーティクルをSphereが近づくとグループBに送るようにしています。
(NodeヘルパーでSphereを指定、Distansで距離を指定)
今回はDistansノードを使用していますが、場合によってはInMeshノードでもいいと思います。
ここで大事なのはDistansノードでグループBに送ると同時にParticleDateノードでAgeを0にしてあげていることです。
(FrameヘルパーノードでAgeを0にしています。)

これはSphereオブジェクトが通り過ぎたときに差し替えたオブジェクトのアニメーションを0フレームからスタートさせたかったためです。
これが無いとグループBに送られた時のフレームでアニメーションを参照してしまい、アニメーションが途中から始まってしまいます。
今回ここをどう処理するか一番悩まされました。出来上がってみるととても単純でしたが…。

◆最後にShapeB_Assignダイナミクスです。
ここはShapeBグループに送られた後(Sphereオブジェクトが通り過ぎた後)のオブジェクトを割り当てなおしています。

◆ここで重要なのはShapeA_AssignダイナミクスのときGeomInstanceノードで割り当てたオブジェクトの順番と差し替えたいオブジェクトの指定する順番をそろえてあげることです。
ただし、そろえるだけでは駄目でGeomInstanceノードでShapeNumberとGroupノードをつなげてあげましょう。

オブジェクトの指定する順番をそろえなかったり、ShapeNumbeをつなげていないとオブジェクトが意図しないオブジェクトと指し代わってしまいます。

◆解説は以上です。
今回これをやりたかったのは、キャラクターが草むらを進むときに草を揺らしたりするアニメーションをテストしたかったのですが、草の倒れる方向や倒れるリアクションに自由度を持たせて自然に見せるにはもっと複雑な仕組みが必要そうです。

現時点の自分ではちょっと手に負えないかな…。
悔しいのでいずれ出来るようにがんばりたいとおもいます。

しかしヒキ絵だったり、たとえばキャラクターが歩いているときに足元で逃げる小さな虫とかに使う分にはそんなに難しく無さそうです。

ノードの詳しい解説などがもっときちんとできるようにもなっていければとおもいます。
解りづらい解説かとはおもいますが、少しでも何かのお役に立てれば幸いです。

2012年1月8日日曜日

マッスルプラグイン Hercules、SkinFxのちょっとした解説

今回Maxのマッスル系プラグインのHerculesとSkinFXを触ってみたので、それぞれ使い方を簡単に解説したいとおもいます。
といっても、まだ少ししか触って無いですし、難しいことは何も無いので覚え書き程度です。
本格作業に入って何か発見などあればまた書いていきたいとおもいます。(書ける範囲内で…(^_^;))

まずこれらのプラグインを試す前に数バージョン前からデフォルトで搭載されるようになったCATマッスルをテストしたのですが、割と使えるかと思いきや、途中でリネーム出来なくなるという現象に見舞われたり、最近のバージョンでは不安定な所があったので今回は見送ることにしました。
CATはせっかくいいプラグインで標準で搭載されるようになって喜んでいたのですが、どうも不具合が多いですね…。
ホント何とかしてほしいものです…。

どちらもだいぶ前からあるプラグインですが、自分は今回はじめて触りました。
Hercules (Di-O-Matic)
http://www.di-o-matic.com/products/plugins/Hercules/#page=overview
SkinFX (Lumonix)
http://www.lumonix.net/skinfx.html


制作事例をあまり聞いたことがあまりないのですが、Maxでのマッスルは皆さんどうしているのでしょうか?
国内ではそもそもあまりMaxでマッスル系プラグインはあまり使われていないのでしょうか??

HerculesもSkinFXも細かい所で一長一短はあるもののさほど大きな差は感じませんでした。(目的は一緒なので当たり前ですが。)

まずおおきな流れとしてどちらのプラグインもスキニングしたオブジェクトに対して筋肉を配置し、専用のモディファイヤで筋肉を登録し、筋肉オブジェクトの動きの変化によって対象のオブジェクトを変形させまはす。

Herculesは機能が限定されている分シンプルで初めて触った時から直感的に触る事ができました。
SkinFXは初め解り難いなぁといった印象がありましたが、慣れてしまえばそんなに問題ありませんでした。

SkinFXはマッスル以外にも色々な機能が付いていて価格もライセンス形態によってはかなり安いです。
しかし、若干不安定な部分な感じもありました。
2012ではビューポート設定がデフォルトでNitrousに設定されています。
この状態だとビューポートでエッジ表示にしたときにMaxが落ちてしまいました。
Direct3Dにすれば問題ありませんでした。
(この辺はマシン環境の問題もあるのかもしれませんが…)

余談が長くなりましたが、解説です。
解説の初めにある、■はHercules、◆はSkinFXの解説です

------マッスルオブジェクト作成------
■Herculesのマッスルオブジェクトは作成パネル>ジオメトリ>StandardPrimitiveから作ります。
◆SkinFXはヘルパーという考えなので作成パネル>ヘルパー>Standardから作成します。
◆SkinFXは前記のとおりいろいろなことが出来るので用途別のヘルパーが用意されています。
 切り替えはSettingnoShapeから行います。

今回はGeoMuscleの解説します。(また余裕が出来たときにでも記事を書きます。)

------各パラメータ------
■ Herculesの筋肉の始点と終点はGeometoryロールアウトのControllerObjectsのOriginとTerminationをクリックしオブジェクトをピックします。
Geometoryでベースとなる形状(半径やポリゴン数など)を調整できます。
■DefomationロールアウトのStretichingMethodで形状変化(筋肉がどのくらい変化するか)の強度を決めます。
■SecondaryMotionは筋肉の揺れ具合を調整するパラメータです。
ヘラクレスではデフォルトでゆれるパラメータがついています。チェックをオフにすると揺れないようにできます。

◆ SkinFXでは筋肉の始点と終点にヘルパーがついた状態で作成されます。このヘルパーをオブジェクトにリンクすることで筋肉を収縮させます。
◆SettingsロールアウトのBlendは形状変化の強度です。
(Blendの値を変えてもSkinFXではビューポート上で確認できません。ここは個人的にマイナス面でした。)
◆Shapeのドロップダウンリストでヘルパーを切り替えることが出来ます。
◆EngineOptionについては省略します。
◆Shape/Capsule/Boxでベースとなる大きさを決めます。
◆MuscleはGeoMuscleを選んだときの形状を調整するためのパラメータです。
◆SkinFXは揺れのパラメータが無いので後からフレックスモディファイヤなどで追加してあげる必要があります。


------マッスルオブジェクトの形状修正------
筋肉の形状を自由に修正したくなるとおもいます。やり方はとても簡単です。
■ HerculesではEditProfileCurveで筋肉の形状を修正することが出来ます。そのほかメッシュ編集モディファイヤを追加することで形状を変化させることも出来ます。




■ Hercules独自の機能でBendingというものがあります。
これは筋肉の中間の位置を指定して動かないように押さえつけることが出来ます。
個人的にこの機能はお勧めでHerculesを好きになったの大きな要因のひとつですw
これが無いとボーンを曲げた時に筋肉そのものが移動してしまうので結果的に正しくありません。
■マッスルオブジェクトが上下移動しなくなりました。


◆ SkinFxで形状を自由に変化させるにはメッシュ編集モディファイヤを使用します。
◆ また筋肉の形状変化が100%に達したときの形状をモーフターゲットを作成して、登録することができます。
やり方は簡単で元のマッスルヘルパーにメッシュ選択モディファイヤを追加します。
スナップショットを取って形状をコピー>メッシュ化します。


メッシュ化したオブジェクトを理想な形状に変形し、PickMorphボタンを押してターゲットオブジェクトをピックします。
(画像ではわかりやすい形にしています)
Tensionパラメータでターゲットの形を100%にしたい状態で100と入力しすぐ右のロックボタン(?)でロックします。親のボーンを元の位置に戻すと形状がはじめの状態に戻るのが確認できるとおもいます。



ここまではベースとなるセットアップをしてきました。

実際にスキンオブジェクト(キャラクター)などに適用する方法を見ていきましょう。
どちらもモディファイヤスタックの順番は元モデル-スキン(フィジック)-それぞれのデフォーマーモディファイヤという形になります。

------マッスルオブジェクトによってオブジェクトを変形させる------


HerculesではHerculesDeformモディファイヤを使用してマッスルオブジェクトを登録してモデルを変形させます。
標準のモーファーモディファイヤのようなインターフェイスですね。
DeformerListでスロットを選択します。
DeformerParametersでオブジェクトを登録します。
Infuence、Smoothing、Pushでリラックスを掛けたり、盛り上がりを強調したりできます。






◆SkinFXではSkinFXモディファイヤを使用してマッスルオブジェクトを登録してモデルを変形させます。
Toolsにあるピックボタンをオンにしてマッスルオブジェクトを選択すると登録できます。
登録しただけではどの頂点にも割り当てられていない状態です。
MuscleToolsボタンをクリックするとメニューが現れます。
そこからFill All 100%ですべての頂点に対してマッスルオブジェクトが割り当てられます。
ポリゴン数が多いメッシュだと重くなってしまいます。



とりあえずマッスルオブジェクトによる変形が出来ました。
ただし、画像にあるとおり変形させたくない部分まで変形してしまいました。
回避方法は特定の頂点に割り当てなおせばいいだけです。

Hercules


◆ SkinFX


------特定の頂点に割り当てるには------

■ HerculesではHerculesSelecterを使用します。
これは頂点を選択し名前で登録しておくためのモディファイヤです。
HerculesSelecterで頂点を選択します。
名前を入力し、Createで頂点を登録できました。(頂点の選択セットのような感じですね)
HerculesDeformのスロットに登録したマッスルに対する頂点を割り当てます。
HerculesDeformでスロットを選択します。DeformerParametersのChooseSelectionのドロップリストに登録した頂点の名前が出てくるので割り当てたい頂点のセットを選びます。

◆ SkinFXではペイントウェイトによってマッスルを任意の頂点に割り当てます。

SkinFXモディファイヤのToolsのリストでマッスルオブジェクトの名前を選択します。

WeightsのPaintをクリックするとブラシツールが現れるので、標準のペイントウェイトと同じ感覚で重みを設定します。



ここはSkinFXのほうが解りやすいですね。(個人的には頂点ペイントはあまり慣れて無いせいか…塗りムラができるので好きではありませんが…)

解説は以上です。
もし、こういった方法あるよーとかこっちのほうがいいよーとかありましたら。
コメントなどいただけるとありがたいです。
もし、また何か発見いたしましたら記事にします。
使い方は簡単ですが、実際キャラのどこに仕込むべきか、どう仕込めば効果的か探るのが難しいですね…。



元々文章能力が乏しいうえに初めての記事ということでだいぶ時間がかかってしまいました…。
駄文乱文お許しください。