WebGL研究 (2) PixiJSとp5.jsのパフォーマンス比較
前回に引き続きWebGLのパフォーマンス研究です。今回はGLSLは一旦お休みして、パーティクルを使った定番プログラムで、p5.jsとPixiJSの比較を行ってみました。まさかこんなに早いとは・・・
お題
パーティクルの座標と速度を変数 (配列) で管理して、毎フレーム座標を更新、再描画を行う。カンバスサイズは少し欲張って1920×1080。
フレームレートは無指定 (60fps目安) で、安定して50後半が出ればOKとする。
検証環境
松) Macbook Pro 16' (Apple M1 Pro / 10コアCPU、16コアGPU)
竹) Macbook Air (Apple M1 / 8コアCPU、8コアGPU)
梅) iMac 27' 5K 2017 (4.2 GHz クアッドコアIntel Core i7 / 64 GB 2400 MHz DDR4)
p5.js
まずはベンチマークとして、Processingの文法でほぼOKなp5.jsです。
松) 9000粒
竹) 8000粒
梅) 2000粒 (30fpsなら4-5000粒いけるが、安定しない)
PixiJS
続いてPixiJSです。レンダリングはGPUを使ってWebGLで行われます。
描画系のAPIを利用するp5.jsと違って、PixiJSでは予めパーティクルのSpriteを生成し、ステージ直下の親SpriteにaddChild。毎フレーム座標の更新を行っています。(Spriteの再生成はしない)
※ 描画系のAPIで粒を都度書いたりすると、こんな速度は出ませんでした
松・竹のM1 Pro / M1 で5倍の結果が得られました。さらに、梅のiMacで10倍以上処理できたことに驚き。Intel世代のMacの方が得られる恩恵が大きく、パフォーマンス差が少なくなりました。
松) 45000粒
竹) 40000粒
梅) 35000粒
PixiJS (ParticleContainer使用)
ここからさらに最適化を行いました。ParticleContainerというParticle管理に特化した親オブジェクトをつくり、ステージ直下に配置。その中にパーティクルSpriteをaddChildしてみました。
ParticleContainerの場合、中においたSpriteのvisibleを変えても無視されるなど、高速化のために限られたプロパティのみを扱っているようです。 (初期化時にチューニング可能で今回は初期値でテスト)
通常のSpriteを親にするのに比べ、さらに3倍は早い印象です (p5.jsの15倍!)
松) 140000粒
竹) 130000粒
梅) 120000粒
まとめ
今更ながらGPUのパワーを思い知り、次にテーマにするとしたらPixiJSの深掘りかな、と思いました。なんだかFlashをやっていた頃が懐かしい・・楽しい・・
Processing (p5.js) でつくってフルスクリーンで展示しようとしたら描画速度が・・という方も、あきらめずにGPUを使える開発環境を模索してもらえたらなと思います。