シリーズNiagara第三弾。前回記事はこちら。
前回、パーティクルを引き寄せるアトラクタを作った。今回はその逆。パーティクルを払いのけるような動きをする「リペラー(Repeller)」モジュールを作成した。
完成品
ヤバイ。超かっこいい。 #UE4 #Niagara pic.twitter.com/VIyEoFL0NP
— ai (@ai_9684_dct) July 13, 2018
環境
UE4.20 preview5
参考にしたサイト
Nature of Code -Processingで始める自然現象のシミュレーション- のp148以降に紹介されているアルゴリズムを流用。
Nature of Code -Processingではじめる自然現象のシミュレーション-
- 作者: ダニエル・シフマン,Daniel Shiffman,尼岡利崇,鈴木由美,株式会社Bスプラウト
- 出版社/メーカー: ボーンデジタル
- 発売日: 2014/09/16
- メディア: 大型本
- この商品を含むブログを見る
こちらの本は英語版が無料で公開されており、全ソースコードもGitHubで公開されている。
今回流用したアルゴリズムのProcessingソースコードはこちら。
Module Scriptの概要
全体図
万有引力公式で得られるベクトルに-1を乗じることで反発方向への速度ベクトルを取得している。
解説
Map Getで Partice.PositionとPartice.Velocityを取得。Particle.○○は各パーティクルが持つ変数のこと。
続いてMap GetのModule -> Make New、もしくはParametersパネルのModuleから
- Module.RepellerPoint
- Module.DistMin
- Module.DistMax
- Module.Strength
を追加する。Module.○○はそのモジュールの中だけで使えるローカル変数で、エミッター編集画面で編集することが出来る。
Module.RepellerPoint - Particle.Positionで反発点とパーティクルとの間のベクトルを取得できる。このベクトルをNormalize(正規化、長さ1のベクトルに変える)、Length(ベクトルの長さを取得)につないでおく。
反発点とパーティクルの間の距離を万有引力公式の距離に当たる部分に突っ込めば反発力が得られる。が、例えばRepellerPointと全く同じ位置にパーティクルが生成されるとそのパーティクルはずっと動かなくなり、RepellerPointとかなり離れた位置に生成されると、その距離の二乗で割ったものがパーティクルにかかる力となる都合上、殆ど動きがなくなってしまう。
この問題を解決するため、反発点・パーティクル間の距離をある範囲に制限(Clamp)する。ClampのMinにはModule.DistMinを、MaxにはModule.DistMaxを使用する。
万有引力公式を使って得た力を反発点・パーティクル間ベクトルを正規化したものに乗じる。これは運動方程式に従うと、ある時刻での加速度に当たることがわかる。
加速度がわかればあとはパーティクルの速度を更新するだけ。得られた加速度をParticle.Velocityに加え、Map Setで更新する。
これで完成。ちなみに冒頭紹介した動画は、前回記事のもののアトラクタモジュールをリペラーモジュールに差し替えただけで、そのパラメータは
- DistMax 100.0
- DistMin 10.0
- RepellerPoint 0.0, 0.0, 0.0
- Strength 20000
に設定している。
あとがき
引き寄せが作れたから反発を実装してやろうと軽い気持ちでつくったものだが超エモいエフェクトが出来た。Niagara、本当に面白い。