資料館/E3Dのパーティクルが重いと嘆いた私

Last-modified: 2007-12-21 (金) 13:39:12

きっかけ

手っ取り早くイカしたエフェクトを出すため、パーティクルは無くてはならない。
当時パーティクル覚えたての私は、ここぞとばかりに突っ込みまくった。結果、開発環境でFPSが30出ないという状況に陥ってしまった。
開発環境でフルフレーム出ないゲームなど論外。うんこ。ということで、試行錯誤が始まった。

原因

んで、結論として、パーティクル発生の処理が重たい(当たり前か)ということが分かる。
E3Dでは、パーティクルに重力などを設定し、命令が呼び出される毎に何個パーティクルを生成するかを決めてやることにより、美しいパーティクルを簡単に描くことができる。
で、今まではパーティクルの生成が必要ないとき、その生成数に0を設定していた。
しかし、生成数を0にし、画面内にパーティクルが無い状態でもE3D内部で何か大人の事情が動いているらしく、速度が落ちていたのである。これに気付くのに4日はかかった。
オイラのゲームはユニット一体につき、弾道パーティクル15、ブーストパーティクル最大4、被弾時の火花などのパーティクルを持っているため、処理的にかなり重たいようだ。

解決策

重たい理由が分かってしまえば、対処法を考えることが出来る。
パーティクルが消えた時は、パーティクル描写命令自体を呼ばない
これに尽きる。というかこれって常識だったりする?

具体的な流れ

それで、パーティクルを止める、という処理3パターンを比較するプログラムを作ってみた。

  1. E3Dsetparticleemitnumでパーティクルの生成数をゼロにする
  2. フラグによってパーティクルがいらなくなったら即座に描写命令を呼ばなくする
  3. フラグとカウントで、いらなくなった後も暫くは描写命令を呼び続ける



ON、OFFフラグによってパーティクルの生成数を0にしても、直ちに画面内のパーティクルが消えるわけではない。今まで生成されていたパーティクルが消えるまで、つまりOFFになったフレーム―最後のパーティクルが消えるまでは描写命令を呼んでやらないと、パーティクルがいきなり消滅して不自然だ。
パーティクルの生成数だけ0にして、ずっと描写命令を呼んでりゃいいじゃないですか、というのも結論だが、上記したとおりオラの環境では山盛りのパーティクル描写命令がFPSを大きく下げているため、別途カウンターを設けてパーティクルの描写命令を制限することにした。



これらの動作を適当に比較するサンプルを作って添付しておくので、HSP3.1でコンパイルすれば、それぞれの挙動を比較できる。

なお、実行にはE3DHSP3が必要。バージョンは新しければ大丈夫だろう。
サンプルコードでは、描写するパーティクルが一個だけなので全く問題ないが、これが100個とかになれば結構な差が出るのである。