【UE4】【Niagara】動かし方の考え方や、モジュールを弄ってみる
Niagaraで、実際に数値をあれこれして部分を、自分で調べたり試した部分を書いていきたいと思います。
既存のモジュールを使うのみであれば、カスケードと変わらないとは思いますが
既存のモジュールでは数値の持ち方的に使いにくい!などの場合
カスケードとは違い、非常に簡単にモジュールの中身を弄ってあげる事が出来ます。
ただし、既存モジュールのデータそのものを変えないように、上書き保存はしないように注意してください。
まずは、基本的な動かし方から
単純に色を変えるだけであれば、ParticleSpawnに、Colorのモジュールを追加して
このようにRを100に変更すれば。
エミッシブカラーにより、この様に発光する表現となります。
ここで、このColorモジュールの中身はというと
見にくいかもしれませんが
赤で囲った部分が、InputとOutput
黄色がGetとSet
紫が加工している部分
BP触った人であれば大体把握できそうな内容ではあると思います。
モジュールの新規作成をすると出てくる、この繋ぎ方が基本になってくると思います。
Inputから、GetとSetに繋ぎ
Setの出力をOutputに。
次は、ColorモジュールのGetとSetに入っている内容について。
Getの中身はこのようになっています、上から
Module.Color
Module.Scale Color
Module.Scale Alpha
この三つになっています、一番重要なのは、頭に「Module.」と付いていることです。
Niagaraは、この最初の部分はしっかりした命名規則があります。
具体的には、「Module.Color」を「Color」に名前を変えてしまうと動かなくなります。
自分は最初これやらかしました...
この頭の「Module.」は、エミッター側で入力した数値を受け取る処理となります。
つまりこのモジュールの場合
「Color」「ScaleColor」「ScaleAlpha」
この三つをエミッターで入力できるように作られているわけです。
実際にエミッターを見てみると、同じ名前のパラメータがあると思います。
一方、Setの方はこちら
Particles.Color
が一つだけ存在します。
こちらは、基本的に名前は変えないほうが無難です、この状態で、1文字でも変えると機能しなくなります。
「Particles」は、受け取った数値を、実際に動かす処理となります。
基本的にはSetに入れることになります
その後のColorは、言うまでもなく、色を変更するという処理となります。
なので、これは受け取った数値を、色に適用する、という意味合いとなります。
「Particles」系は、実際に動かすのでSetに入れるのが基本になると思いますが
Getに入れることも可能です。
Getに入れる場合の目的としては、現在入っている数値を取得する、というものです。
具体的にColorで示す場合
このように設定したと仮定する場合
GetにあるColorで、例えばRが100の場合
Setにある、動きを示すVelocityに繋いだ場合
Rの100の数値を移動量のXに変換するので、Rが100の光っている赤の場合、上に動く処理となります。
また、この「Particles」系の数値は、自分で新たに定義する事もできます。
左のParameterという部分から、新しく追加することもできるのですが
この一覧には、ColorやScaleなどの他に、Flotなどもあります。
Flotなどで追加する場合、この数値で直接動かすというより
一度変数のような感じに数値を保存しておき、ほかのモジュールで実際に動かす、という処理が可能となります。
モジュールからの他に
エミッターのCreateNewParameterという項目からも追加可能です
項目の部分でダブルクリックすると、名前の変更が可能です
これは、自分が勝手に定義したPositionRandというパラメータ
単体では、何も意味を成しません。
移動距離のランダムを作るために作っています。
Minを0.5、Maxを1にしたばあいには、0.5~1の数値をランダムに持つようになります
こちらは、既存のAddVelocityのモジュールの中身に組み込んだ図です
元々Setに繋いである部分を、Multplyに繋ぎ
Getには、先ほど自分で作ったものを入れ込み、これと乗算させます。
こうすると、AddVelocityの数値を定数にしていても、PositionRandの数値をランダムにすれば、移動量にばらつきを出すことが可能です。
【ここまでのまとめ】
モジュールを弄って使いやすくする場合は
パラメータの命名規則をしっかりと把握しよう!
【最後に】
最後に、何故この様な、態々新しいパラメータ定義した例を出したのか、に付いて。
この段階だと、移動量をランダムにする場合、Velocityを乱数にすればいい、と思う方が居ると思います。
この段階ではそれで全く問題有りませんが、個人的な感想としては
ノードベースなNiagaraの利点があまり生きないのでは?と思います。
最後の例で、結局何がしたいのか?と説明すると
「制御用のパラメータを個別に作って定義できる」
ある程度データ作った方だと経験ある方結構居ると思いますが、データが増えてきて場合、調整したいとあった場合、非常に色々な部分を調整する必要が出てきます。
その場合に、調整用のパラメータとして、作っておくことが出来る、というのが理由です。
この辺はNPCというのもあるのですが、それは現在色々調べ中なので次の機会にするとして...
パラメータとして持てるものなら、何でも調整出来るというのが、このやり方のポイントで
中心から、外に大量のパーティクルが放出されるエフェクトの場合。中心部分が重なってしまう、となった場合。
移動量を元に大きさを弄ることで、重なりを少なくして、描画負担を軽くしたり、αを弄ることで綺麗に見せたり、そういう事も恐らく可能なのかな、という事です。
(具体的なやり方は、この辺は現在調べ中なのでお待ちください)
外部ツールを使うわけでもなく、現段階だとナイアガラの方が情報も少ないと思いますので
折角ナイアガラを使うのであれば、ちゃんと利点を生かして使うことが出来ると良いのでは?と自分は考えます。
エフェクト全体として情報少ないという話もあるので、この記事を見てる方もエフェクト関係の情報を出す人が増えてくれればいいな、と考えています。
【UE4】Niagaraを触ってみる
各Ver
UE4:4.20.1
UE4の新しいパーティクルシステムであるNiagara、ある程度触ってきたので、そろそろ記事の方も書いていきたいと思います。
【ナイアガラの有効化】
プラグインから、FXという項目、もしくはNiagara、と検索すると出てくるので有効にしましょう。
【Niagaraのデータ】
Niagaraのデータは、コンテンツブラウザの右クリックの、FXという項目の中に入っています。
基本になるものが
・NiagaraSystem(NS)
・NiagaraEmitter(NE)
・NiagaraMouduleScaript(NM)
上からシステム、エミッター、モジュール
この三つは、カスケードの頃にあったのと似た様なものだと考えれば大丈夫です
ただ、今回はそれぞれ別々のアセットで保存されます。
現段階では、まだアイコンらしいアイコンは実装されていないので、Niagara系のデータだけでこんな感じになります。
これ以外のアセットである
・NiagaraDynamicInputScript(ND)
・NiagaraFunctionScript(NF)
・NiagaraParameterCollection(NPC)
・NiagaraParameterCollectionInstance(NPCI)
この4種類、まだまだ曖昧な部分があるので間違ってる部分もありそうですがわかる範囲で書いておこうかと思います。
※()内は略称です、正式な略称かは不明
【NiagaraDyamicInputScript】
直接開くと、NMと似たような構造になっています
グラフの部分はこちらです
一方、NMは
このようになっています
NMにはMapSetというノードが多く、一番最後のOutputが変わっています。
重要なのが、どこに使われているのか?という事ですが。
NMの中に入っている様なイメージです。
NEの要素を動かしたりするのに、NMを使うわけですが(移動や大きさ等)
その数値をあれこれするのに使います。
カスケードで例えると
例えばLifetimeのモジュール
パーティクルの寿命を設定するためのモジュールになります。
そしてこのモジュールの中の
この赤枠の部分、これがNDになると考えると解りやすいと思います。
また、これによって何が便利なのか?というと
NMは、入れる数値の型を指定する必要があるのですが、これを別の型でも使えるようにしてくれます。
これはモジュールの一部を写したものですが。この頭にMouduleとある部分は、エミッター上で数値を入れることができます
ただし、この場合上はColorの4チャンネルの情報
その下は3チャンネル、その下は1チャンネルの情報しか入れることができません。
このモジュールをエミッターに入れた場合、この様な表示となります。
エフェクト作っている方であれば、解ると思いますが、この場合色ですが、完全に固定の色しか入れれないのは困りものです。
大量に飛ぶ粒子などは、ある程度色のランダム性を持たせると綺麗に映りやすいですし、これは位置などにも言えるので、かなり規則正しい動きになるのは、エフェクトにおいてはあまりよろしくない場合が多いです。
このモジュールの数値を入れれる右端に▼マークがあるのですが、ここをクリックするとメニューが出てきます。
そこからUniform Ranged Floatを選択すると、ここの数値の最大値と最小値を指定する事ができるようになります。
下の画像の、赤線の部分、これがNDになります
ダブルクリックで、中に入って編集する事も出来ます...が
カスケードと違い、このデータ自体が編集できるアセットになっているので、ここを編集して保存すると、ほかのエミッターで出したときにも、その編集した後になるので注意が必要です。
共同製作の場合、ここをいじる場合、ほかの方の作ったアセットに悪影響が出かねないので、別名で保存するなどの配慮が必要になります。
【NiagaraFunctionScript】
こちらは、よくある関数になります、BPやマテリアルにも同様の機能があるので、ここは飛ばさせてもらいます。
【NiagaraParameterCollection】
マテリアルにも、似たような機能のある、パラメータコレクションです
パラメータコレクション、という機能自体の説明としては
パラメータコレクションを参照している数値を、全て一律に変えることができる、という感じでしょうか
また、これは動的に変えることも可能です
マテリアルでもあるのですが、マテリアルインスタンスでも動的に変えることができますが最大の違いは、参照してるもの全て同時に変えてしまうということです。
マテリアルインスタンスの数値を変える場合、変更するマテリアルのデータを参照して動かしますが、パラメータコレクションはすべて変更してしまいます。
こちらが、NPCを変更するための、BPのノードです。
左側のが実際に変更するノードですが、MIDなどと違い、ターゲットのピンがありません。
なので、参照してるもの全てを変更します、軽い気持ちでこの機能で動的に変えてしまうと、変えたくない部分まで変わってしまいます。
実用的にNPCを使う場合はどうしたら良いかな?と考えたのですが、モジュールなどに入れるのがいいのかなと。
動かす内容としては、動的に動かすのではなく、全体を一律に調整できるパラメータとして使ってみよう、というわけです。
まずは、モジュールにNPCを適用する方法を。
NPCアセットを作ったら、右の方にある、AddParameterから、パラメータを作ります、名前もとりあえずつけておきましょう。
モジュール側で作ったNPCを追加する場合は
ParameterCollectionの右にある+のマークから、追加していきます。
MapGetのノードから追加することも可能です。
このように追加されれば大丈夫です、あとは、ここからの数値が、常にNPCで設定した数値になるようになります。
長くなりそうなので、実際の数値の運用関係は次の記事で纏めます。
【Niagara Parameter Collection Instance】
所謂、NPCのインスタンス版、だと思うのですが、これに関しては色々試そうとしたもののあまりわかっていないのが現状です...
というのも、NPCをセット出来るところでも、基本はセットできない作りになっているようです
モジュールなどの入れる場所で、NPCが入るところにそのままでは入れれないようです。
また、BPでNPCを操作できるノードがありますが、ここにNPCIが入る事もできないようです。
このアセットの運用については、今のところ調べてみようかなと思っています。
具体的な動かし方等は、次以降の記事で書いていきたいと思っています。
組み込み関係やっていました
【UE4】オーラっぽいエフェクト
今回は、UE4のマテリアル周りの記事です。
Verは4.18です
今回はオーラっぽいのを作ってみようかと思います。
記事に書くって言ってて、まだ書いてなかった、こういうやつの記事書きます... pic.twitter.com/0aFefCeJs5
— moyasi@エフェクト勉強中 (@torisutamoyasi) June 10, 2018
動きとしては、こんな感じになります。
ただし、今回の記事は割と簡易的なやり方になります、ご了承ください。
必要なテクスチャ
今回は、この二つを使います
作り方はこちらを参考にしてください、ノーマルマップの方は、右側のを、法線ノードでノーマルマップに変換しただけのものです。
基本的に簡易的なテクスチャなので、色々試してみてください。
マテリアルの構成
マテリアルの構成はこんな感じです。
特に変わった点は無いかなとは。
ParticleRelativeTimeはあまり見慣れなさそうなノードなので、一応個別の記事も貼っておきます。
原理的には、非常に単純で、メインとなるテクスチャの、UVsの接続にノーマルマップを適用することで、歪ませることで、描画を変えています。
また、RelativeTimeを使うことで、徐々に歪みを強くすることもできます。
カスケードの設定
そこまで複雑ではないですが、カスケード側の設定も。
・デフォルトにある、InitialVelocityのモジュールは削除します。
・マテリアルを先ほど作ったものに差し替えます。
・OrientatintのLockAxisでZ軸を固定します。
・InitialSizeの拡大率を50~2
5のランダムに変更。
・SizeのSizeByLifeで拡大率を0→5ほどに変更。
・RotationからInitialRotationを追加。(設定はデフォルトでOK)
・ColorOverLifeのモジュールを削除。
・Colorから、InitialColorと、ScalaColor/Lifeを追加。
・InitianColorは今回の例だと、RGBがそれぞれ0~1になるように。
・ScaleColor/Lifeは、RGBとも10程から1まで変化
αはこちらを参考に、フェードインとアウトをカーブで作っていきます。
Spawnは、連続的に出てる方では、Rateが5
単発で出てる方は、BurstListで3
これで、最初の方に貼ってある動画のような挙動になると思います。
今回は、マテリアルや動きは基本短調でしたが
こういうオーラっぽい表現好きなのですが伝わりますかね... pic.twitter.com/1f1hGArLLn
— moyasi@エフェクト勉強中 (@torisutamoyasi) May 19, 2018
もうちょっとマテリアルや、カスケード側の設定を凝ればこんな感じになります。
UVsに接続するのを、DyanamicParameterを使って細かく制御したり、ParticleRandomValueを使って、発生ごとに歪みの強度を変えたり、色のランダム性を、テクスチャを使ったりなど。
かなり色々な用途はあります。
一番シンプルなのは、歪みに使うノーマルマップを変更する事です。
制御しやすくする方法としては、最後にマスク用のテクスチャと乗算したり。
歪みの強度を、ScalaParameterで調整出来るようにしてから、インスタンス上で強度を調整したりすると、どのような表示になるのか?などの確認がしやすくなると思います。
今回はここまでです、是非色んなノーマルマップのテクスチャを使って試してもらえれば、と思います。
【UE4】マテリアルでディゾルブエフェクト
Verは4.18です
こういうオパシティマスクと、発光を組み合わせた様なものを、ディゾルブエフェクトというらしいです。
#UE4
— moyasi@エフェクト勉強中 (@torisutamoyasi) June 7, 2018
ディゾルブは最終的にこんな感じ
調整用パラメータは3つあり、それぞれ0~1で変動するのを基本に
負の数値や1を超える数値も入るのは入ります。 pic.twitter.com/CIjURO46pS
実際の動きはこんな感じになります。
また、カスケードなどで使いやすい様に、1~0の数値だけで調整できるようにしてます。
このエフェクトの作り方自体は載っていたのですが、数値の調整まではなかったので、その辺は自分で色々調べました。
全体の構図
全体の構造はこの様になっています。
動きとしては、ノイズを元にオパシティマスクで消えていく部分と
消える前に、エミッシブカラーにより発光させています。
各パラメーターの動き
ScalaParameterにしているのは、この3箇所です
1.全体の欠け具合を調整するパラメーター
名前はBaseParameter
こちらは主にParticleColorなどで1→0に動かすことを想定しています。
左が0.6で、右が0.3です。
2.発光部分面積の大きさを調整するパラメーター
名前はEmissiveLine
こちらは、主にマテリアルインスタンスなどで、設定するのを想定しています。
左が0.1で右が0.3です
この例では0.1と0.3ですが、実際に使う場合は0.1~0.2位が綺麗に見えやすくなるかと思います。
3.発光の掛かり具合を調整するパラメーター
名前はEmissiveLerp
こちらも、主にマテリアルインスタンスなどで、設定するのを想定しています。
左が0で右が1です
変化が若干解りにくいパラメーターでもあるので、0か1のどちらかを推奨します。
体感的には、発光する面積を調整するパラメーターが小さい場合は高くしたほうが、大きい場合は小さくしたほうが綺麗に見えやすいと思います。
また、拡大すればするほど、数値は小さいほうが自然に見えやすくはなると思います、この辺は使う用途によって使い分けてください。
中身の解説
まずはこの部分、この部分に、基準となる数値と、発光する幅を設定するパラメータが入れてあります。
3種のパラメータは解りやすいように省略します
・BaseParameter(以下BP)
・EmissiveLine(以下EL)
・EmissiveLerp(以下ELerp)
赤枠にある、IFは、最初の発光部分のみなのか、オパシティマスクで消すのかどうかを判定しています。
Addの部分は、ELとBPを加算しています、その結果が1以上なのかどうかを判定。
1以上であれば、発光のみとなります(ELが0.2であれば、BPは0.8まではオパシティマスクで消さないことに)
1を切った場合に、IFの判定が代わり、ここからオパシティマスクで消していくことになります。
ただし、そのままでは0~1の数値で調整できないのでノードであれこれしてます。
具体的にはこの部分です、ELを反転させたものを、BPから割り、その後Clampで0~1に
ELが0.2と仮定した場合、オパシティマスクでの消滅はBPが0.8→0で完全消滅させる必要があります(1~0.8は発光のみにする必要が)
反転で0.8にした数値を割ると0.8以上が1以上になります(超えた分はClampで消してます)
これにより、BPが0.8であれば1になり、0であれば0になります、同じ数値で除算すれば1になります。
これを、IFのA<Bに繋げることで、BP+ELが1を切るまでは、ELの発光のみを行い、1を切るとBPの数値により消滅していくようになります。
ELの数値によって、消え始めが遅くなる関係上、この数値が大きいほど、消える速度も速くなります、これは全ての数値を0~1で調整しやすくする為です。
今回、オパシティマスクが0で消滅させたほうがわかり易いので、オパシティマスクに繋ぐ直線に、0.3333をAddにより加算しています。
発光部分
次はエミッシブで発光させる部分です。
この部分のノードはこうなっています。
発光Lerp-AとBがありますが、これはELerpでの発光の2種類になります、切り替える必要が無ければいりませんが、どうせならと作ってみました。
まずはLerp-Aの部分から
発光させる部分を0~1の数値で取得して、エミッシブカラーと乗算する事で、グラデーションの掛かった発光を作ります。
赤枠は、接続先が見えませんが、ELと繋がっています、ELは0.2として進めていきます。
基本左から右にどんどん繋いでいます
最初はELを反転します、これで0.8に
その次のAddは
この部分の出力と繋がっています
その後のClampで0~1(1を超えた分を切り取り)の後に反転します
これで1以上になった部分は全て0になります
その後に、ELを割ったものをエミッシブカラーのベースと乗算して完成です。
内容がややこしそうだと思うので、中身を細かく...
最後の反転までは、エミッシブカラーで発光させる部分を取得する為の処理です、0は一切発光しないが、それ以上は発光させる。
発光させる部分というのは、オパシティマスクで消滅させる数値より、ELの数値(今回は0.2)高い以下という事です。具体的には0~0.2が該当します。
なので、ノイズと減算してる部分から、0~0.2の範囲を取得する必要があります、これ以上を切り取る必要があります。
この為に、反転したELを加算します、0以下は、オパシティマスクで消しているので、考慮する必要がありません、なので必然的に0.8を加算するので、0.8以上になります。
(0以上の数値に0.8を加算します)
ただ、0.8以上で上限があまりないので、Clampにより、0.8~1の間に抑えます
その後反転する事で0~0.2の数値を取ってくる事が出来ます、この数値だと少ないので、元のELで割る事で0~1になるので、これをエミッシブカラーと乗算します。
つづいて、Lerp-Bの部分です。
赤枠は、エミッシブカラーで発光させる基本の色と接続しています
黄枠は、ELと接続しています
こちらは、グラデーションが殆ど無い版です。
真ん中にあるIFで、まず発光させる部分であるかどうかを判定します。
判定基準はノイズを引いた数値がELの数値以下であるかどうか、判定基準としてはLerp-Aとは変わりません、以上かどうかによって、定数の0or1を出力します。
IFの後のこの三つのノード
発光させるだけであれば、IFとエミッシブカラーを乗算させるだけでもいいのですが、反転も組み合わせると、ちょっとだけグラデーションが出てきます。
この辺は好みでいいかと思います。
ELが0.5でこの位の差になります、ほんのりグラデーションを与えます。
最後に、作ったLerp-Aと、BをLerpに繋げば完成です。
今回は、エフェクトで使いやすいように0~1で調整できるように、を主体でしたが
0~1といえば当然テクスチャもそうなるので、ELやELerpな
どにも、ノイズテクスチャを適用してみれば、面白い模様にもなるのでは?と思っています。
例えばこちら、ELerpに、 texturecoordinateのR情報を取ってきて適用したものです
中心付近でクッキリ変わっているのが解ると思います。
【SD】オーラっぽいテクスチャを作る
Verは2018.1.1です
以前に作ったものなので、一部記事内でノード差し替えてます
SubstanceDesignerでオーラっぽいテクスチャを。
全体の構造
大きく4つに分けます
1・全体の明暗を調整する部分
2・一番のベースとなる模様
3・タイリングの誤魔化しとして、ベースに混ぜる模様
4・1~3の要素の合成&最後の調整
1.全体の明暗を調整する部分
ノイズのこのノードをベースにします
このノードを二つ作り、数値を調整して違うパターンにします
これを、指方向ブラーで上下にブラーを掛けます、角度の回転を0.25にすると、上下のブラーに変化します。
その後、トランスフォームのこのノードで角度を変更します。
最後に、ブレンドノードで、乗算で接続します。
所々黒っぽい部分を作りたいので、片方は全体が白っぽく、もう片方はちょっと明暗を強くすると、綺麗になりやすいです。
ベースのノイズのコントラストや、座標を調整していきます。
2.ベースとなる模様
一番の下地となる模様です。
Perin Noise1がVerで無くなったようなので、差し替えてます。
ノイズのこちらを
パターン違いで同じノードを二つ使います
比較的大きくした後に、レベル補正で明暗をある程度はっきりするように調整します。
大体こんな感じでしょうか。
レベル補正したものを、両方ブレンドノードに繋ぎ、合成方法は最小(暗)で。
この時点で、一番左のようなのになると思うので、再びブレンドノードで
今度はOverlayで合成します、これでコントラストがハッキリします。
その後はトランスフォーム2Dで、高さを20%にする事で、細長くしてタイリング処理を行います。
最後の微調整の部分
使うノードはパターンのこちら
Rotationで横から縦にして、タイリング処理を切った後、Tilingのパラメータで細くしていきます。
その後、トランスフォーム2Dで左右に分かれるように位置を調整した後にブレンドノードで減算して、左右を暗くします。
不透明度は少し低めに(今回は0.25にしています)
3.ベースに混ぜるノイズ
ベースになるのはこのノイズです
綺麗に見せるコツとしては、赤枠の部分の様な大きめの黒い部分を極力なくす事です。
続いて、調整のこのノードで、白黒を反転させます
その後は、このノードを二つブレンドノードで、加算させて白を強くします
最後にトランスフォーム2Dの、高さを25%にしてタイリングさせます。
4.合成&調整
この部分は、1,2,3で作った部分です、それらの合成です
下側のブレンドは最大(明)
右側のブレンドはSoftLightです。
この状態だと、タイリングがやや目立ってしまってもいるので、ちょっと誤魔化します。
トランスフォームのこのノードを
斜めにズラすようなノードで、これによってタイリング部分を多少誤魔化します。
その後、指方向ブラーで左右にブラーを掛けます(この部分は、個人によって好みが別れそうです)
最後にトランスフォーム2Dで回転させて完成です。
なお、最後に極座標変換するトランスフォームのこのノードを使えば
この様な見た目に、
その後、パターンのこのノードなどで円を作り
ブレンドノードで乗算すればこの様にもできます。
単純な板ポリに貼る場合には、中々使い勝手があると思います。
こういうオーラっぽい表現好きなのですが伝わりますかね... pic.twitter.com/1f1hGArLLn
— moyasi@エフェクト勉強中 (@torisutamoyasi) May 19, 2018
このエフェクトのメインの部分に使ってます
極座標掛けずに、モデルに貼る使い方だとこちら
#Effekseer
— moyasi@エフェクト勉強中 (@torisutamoyasi) January 28, 2018
配信で作ったやつです
地面から水流が流れる水属性攻撃魔法イメージです
制作時間は約1時間半
早いのか、遅いのかは、想像にお任せします。 pic.twitter.com/sRP3yN1znt
中心の柱部分の模様みたいな部分に使っています。
【Houdini】行列を使って外側に向ける
Houdiniでのモデリング関連の記事です。
Houdiniでメッシュ作るときに便利そうなものを、メモ代わりにも書いていこうかなと。
というわけで今回は、行列とか使って外側に向きを向けようかなと。
下準備とか色々
ノードツリーとしてはこんな感じ、Tubeでベースを作って、CopyToPointで複製します。
Fuseは、ポイントが重なってる部分を結合しています。
ポリゴン数を無駄に増やさない為にはあったほうがいいですが、処理自体はなくても特に問題はありません、ただ若干乱数入れる場合はあったほうがいいかもしれません。
また、形を作る関係上、頂点の部分をグループに入れておきます。
if(@P.y != 0){@group_ypos = 1;}
コードとしてはこちら、内容としては
ポイントのY軸が、0でないなら、yposというグループに入れる、という処理です。
行列を使った動き
vector axis = set(0,1,0); //Y軸の回転軸を変数に保存
vector4 q = quaternion(atan2(@P.x,@P.z),axis);
//角度をatan2で取得してクォタニオン生成
vector pivot = @P; //行列回転のために、位置を変数に保存
@P -= pivot; // 行列回転の為に、一旦原点に移動
matrix m = ident();// 単位行列を生成
vector dir = set(0,0,ch("R")); // 開き角度をシリンダーから取得
translate(m,dir); //開き角度から移動行列を生成
matrix m2 = qconvert(q); //クォタニオンを回転行列に変換
@P *= m; // 移動行列を乗算
@P *= m2; //回転行列を乗算
@P += pivot; // 位置を元に戻す
コードとしてはこちら、また、ノードのGroupにyposといれて、頂点の部分のみ動かすようにしてください。
(青文字はコメントアウト部分)
vector axis = set(0,1,0); //Y軸の回転軸を変数に保存
この部分は、単純に回転軸を取得しているのみ、基本的に正規化する必要がありますが、既にY軸の1のみなので、する必要はありません。
vector4 q = quaternion(atan2(@P.x,@P.z),axis);
//角度をatan2で取得してクォタニオン生成
先ほどの回転軸と、atan2で取得した角度にて、クォタニオンを作ります。
Y軸が赤線部分で、Y軸に回転させるばあい緑の矢印の回転をするようになります。
角度は、atan2により中心からの開き角度をとってきます、2チャンネルの情報で、XとZ軸のみとってきています(Y軸は無視してます)
このように並んでいるジオメトリの、頂点の部分が、中心から見て何度の位置にあるのかを取得します(距離は関係ないです)
vector pivot = @P; //行列回転のために、位置を変数に保存
@P -= pivot; // 行列回転の為に、一旦原点に移動
行列の回転させる場合、Pの位置情報を元に回転させます。
なので、例えばXが10の位置であれば、自転ではなく公転の様な動きになってしまいます、今回だとこれでは都合が悪いので、一旦変数pivotに保存してから、原点に移動させます。
matrix m = ident();// 単位行列を生成
ここで単位行列を作ります、行列関係では基本的に必要になってくるものです。
それをmという名前の変数に保存します。
vector dir = set(0,0,ch("R")); // 開き角度をシリンダーから取得
ここでは、どの位移動するのか?を定義します、今回はZ軸のみで、移動量は後から変更しやすくしたいので、シリンダーから取得します。
入れる数値は定数でも問題ありません。
translate(m,dir); //開き角度から移動行列を生成
先ほどの、シリンダーから取得したZ軸の移動から、移動行列を作ります
作った単位行列と、先ほどの移動値の情報から、移動行列を生成します。
matrix m2 = qconvert(q); //クォタニオンを回転行列に変換
今度は、先ほど作ったクォタニオンから、回転行列をm2という変数名で作ります。
クォタニオンでつくる場合は、単位行列を事前に作る必要がありません。
@P *= m; // 移動行列を乗算
@P *= m2; //回転行列を乗算
先ほど作った、二つ(移動と回転)を乗算させて動かします。
行列同士の乗算では、後ろの方から計算されるのでこの場合
回転行列により回転させたあとに、移動行列で動かしています
移動はZ軸のみですが、その前に回転行列で角度を変えるので、変えた角度からZ軸動くことにより移動する方向が変わってきます。
外側に向くような方向に移動させている内容としては
回転行列を作るときにatan2にて、角度を取得していてその角度を使うのが理由です。
@P += pivot; // 位置を元に戻す
最後に、位置を元に戻します。
前のHoudiniの記事ではごっちゃになってしまったので
これからは少ない部分を細かく書いていけたらな、と思います。