ビデオの内容紹介
GPU によるパーティクルをエミットする (放出する) スプライト エミッタを作ります。前回の標準的なスプライト エミッタと多くの部分が重なりますが、2 つほど注意しなければならない点もあります。
原題 Introduction Particles 5 – Creating a GPU Sprite Emitter
[1] GPU パーティクルはなぜ必要か
まず、GPU スプライト エミッタのためのフォルダを作っておきます。名前は GPUSprite とします。
次に、前回作成したスプライト エミッタのフォルダ Sprite を開き、その中に入っている P_Sparks というファイル (パーティクル システム) を先ほどの GPUSprite にコピーします。
コピーした P_Sparks に P_Sparks_GPU という名前を付けます。
これを メインエディタのビューポート内の GPU Sprite Emitter という展示台にドラッグアンドドロップします。
P_Sparks_GPU をダブルクリックしてエディタ (カスケード) を開き、少し下準備をしておきます。Particle Emitter の左端 (ピンク色の部分=この色がビューポート内右下のパーティクルの数を示す数字の色となっています) をクリックしてカラーピッカーを表示させます。
カラーピッカーで、なるべく見やすい色にします。たとえば、白や黄色などに。
さて、ここで Spawn (発生) の Rate を 1000 にしてみます。すると、下の画像にあるように (CPU による) 処理が追いつかず、パーティクルが途切れ途切れに放出されるようになります。
そこで、Particle Emitter の下のスペースを右クリックして、TypeData から New GPU Sprites を選択してみます。
Collision と Light の機能 (モジュール) にバッテンがついて、使えなくなります (GPU パーティクルを使用すると、このように制約も生じます)。
それぞれのモジュールを右クリックして、Delete Module (モジュールを削除する) をクリックします。
ここで、Spawn Rate を 2000 にしてみると、途切れることなくちゃんと表示されます。
このように GPU は並列処理が得意であるため、パーティクルのように多数のものを表示することに向いています。(GPU は元来、描画処理をサポートするために生まれたものです。)
[2] パーティクルの色を調節してみる
チュートリアルでは、まず、色を調節しています。Color Over Life (パーティクルの一生の色) モジュールを選択して、Details パネルで Distribution Vector Constant を選択します。これは、ベクター (色の 3 要素の値をベクターに入れています) を一定の値として分布 (配置) させるためのものです。つまり、パーティクルが生きている間、色の値が一定で変化しないということになります。(Distiribution については、前回の記事をご覧ください。)
ここでは、R、G、B に値を入れて緑っぽい感じにしています。
パーティクルの流れる向きをメインエディタのビューポートに合わせて、更に、G の値を少し落とします。
メインエディタの Lit をクリックして Exposure → Fixed at Log 0 を選択します。これは、光の露出を固定 (fixed) するものです。目の慣れをシミュレーションする機能を停止して見やすくしています。ここでは 0 として明るさを調整することなく表示されます。
メインエディタでは次のように表示されます。
[3] Bounds (領域) を設定する
このパーティクルには問題があります。カメラを少し回転させると、表示されなくなってしまうのです。
カスケードのビューポートには、WARNING: This particle system has no fixed bounding box and contains a GPU emitter. と書いています。つまり、「このパーティクル システムには、GPU エミッタが含まれていながら、固定したバウンディング ボックスがない」と警告が表示されています。そこで、メニューバーの Bounds の右横をクリックして、Set Fixed Bounds (固定した境界を設定する) を選択します。
バウンディング (境界) ボックスは、負荷を限定的なものにするために必要となるものです。通常、陰に隠れたものは CPU が判断して描画しないようにしますが (カリング)、GPU パーティクルについては GPU 上で実行されていため処理できません。そのため、バウンディング ボックスを使って、描画すべきか否かを決定しています。つまり、視錐台 (frustum つまりカメラの見えている範囲) にこのバウンディング ボックスが一部でも入っていれば描画されることになるのです。
さらに、Bounds をクリックして、バウンディング ボックスを表示してみます。また、Restart Level (レベルを再起動) をクリックします。
これでカメラが回転しても、パーティクルが非表示になることはなくなりました。
[3] コリジョンを設定する
先に見たように、GPU パーティクルでは、通常のコリジョンのモジュールは使用できないので、今は次のようにフロアをパーティクルが抜けてしまいます。
その代わりに、Collision (Scene Depth シーン深度) というモジュールが使えます。
これは、奥行きのデータを保存した Z 深度を利用してコリジョンを実現するものです。下のようにフロアとコリジョンするようになりました。
フロアを抜けることもなくなりました。
Resilience (弾力) を低目にして、パーティクルがあまり跳ね返らないようにしました。
さらにパーティクルの寿命も延ばしてみます。
すると、さらにフロアにダラーっとパーティクルが流れるようになります。
Collision (Scene Depth) を使うと、あらゆるものと低負荷でコリジョンさせることができます。試しに、UE4 のマークのスタティックメッシュを配置してみると、ちゃんとコリジョンします。
[4] ベクターフィールドを設定する
ベクターフィールドとは、格子状になっている平面や立体があって、その格子 (グリッド) に 1 個ずつベクターを置いていきます。このベクターは、そのグリッドに入ったパーティクルの進む方向に影響を与えるものです。イメージとしては次のような感じです。
この矢印 (ベクター) によって、パーティクルが力を受けることになります。
チュートリアルでは、vel_219 (Vector Field) という既に用意されているベクターフィールドを使用していますが、UE4.8 には見当たらなかったので、VelocityGrid60 というベクターフィールドを使うことにします。(どのような力を受けるのかまったく不明です。)
例によって、スペースをクリックして、Vector Field → Local Vector Field を選択します。(Local とは、この場合、「パーティクル システム内に置く」という意味です。)
メインエディタで VelocityGrid60 を選択状態にしておき、
カスケードに戻って、Details パネルの Vector Field の右側についている矢印をクリックすると、先ほど選んでおいた VelocityGrid60 が自動的に指定されます。(ついでに Bounds をクリックして、バウンディング ボックスが表示されないようにしておきます。)
色々と調整していきますが、まず、ベクターフィールドを表示するようにします。ビューポート内の View (表示) メニューで Vector Field をチェックします。
かなり小さいので大きさを変更します。操作しやすいようにかなり大きめにしてみました。
エミッタがベクターフィールドからはみ出しているので、小さなウィジェットをつかんで上下左右に動かします。
次に Intensity (強さ) と Tightness (結びつき) を調整します。Intensity を大きくすると、それだけパーティクルが影響を受けます。つまり、速く動くことになります。Tightness を大きくすると、そのベクトルの影響度が増します。つまり、この値を 0 にすると、影響度はなくなりますが、1 にすると、パーティクルの固有のベロシティ (速度と方向) が無効になり、ベクターのそれが取って代わることになります。次のようにします。
以上の設定でメインエディタのビューポートで表示すると、次のようになります。
かなり、暴れています。さらに、次のようにも調節してみます。
次のようになります。
更に、パーティクルの寿命を延ばします。
パーティクルの速度によってその大きさも変えてみます。
何か不気味なものができました。ロールシャッハテストにでも使えそうです。
更には、ベクターフィールド自体を回転させてみます。例によって、スペースを右クリックしてから Vector Field → VT Rotation Rate (ベクターフィールドの回転速度) を選択します。
X、Y、Z に数値を入れます。
ベクターフィールドの大きさや Intensity / Tightness をさらに調整します。(任意)
次のように表示されました。
[5] まとめ
チュートリアルでは最後に重要なポイントを 2 点述べられています。
1. 必ずバウンディング ボックスを設定すること。
2. 使えないモジュール (たとえば、Light) を使うには、別途そのためのエミッタを作ること。(同じパーティクル システムに)
ということでした。
今回もかなりの長編になりました。お疲れ様でした!