Effekseer
Effekseer は、ゲームや映像向けのパーティクルエフェクト作成ツールです。Effekseer Effekseer は、ゲームや映像向けのパーティクルエフェクト作成ツールです。炎、爆発、魔法、煙、光、斬撃、ヒットエフェクトのような VFX を専用エディタで作り、ゲームエンジンやアプリ側で再生できる JavaScript / WebAssembly ランタイムです。 WebGL と WebGPU の 2 つの backend を選んで利用できます。
デモ
https://scrapbox.io/files/6a11af3865e24daf8cb19a6a.png
WebGL コンテキストの共有
このサンプルのポイントは2つです。ひとつは「Babylon.js と Effekseer が同じ WebGL コンテキスト(engine._gl)を共有して描画する」こと、もうひとつは「1フレーム内での処理順序が厳密に決まっている」ことです。まず全体構成から。
https://scrapbox.io/files/6a11b9ec65e24daf8cb1a974.svg
初期化(initEffekseer)では、この共有関係を次の順序で組み立てています。
loadScript で effekseer.js を読み込み
→ Effekseer.initRuntime(wasm) で WASM ランタイムを初期化
→ Effekseer.createContext()
→ ctx.init(engine._gl) で Babylon.js が握っている WebGL コンテキストをそのまま Effekseer に渡す(ここが核心)
続く ctx.setRestorationOfStatesFlag(true) は、Effekseer が描画後に WebGL のステートを元に戻すための重要な設定です。最後に ctx.loadEffect(.efk) と ctx.play() でエフェクトを再生します。
毎フレームの処理順序
同じコンテキストを2つのエンジンが触るため、毎フレームの処理順序が崩れると描画が壊れます。その順序を整理したのが次の図です(緑=Effekseer の処理、青=Babylon 本体の描画、橙=両者をつなぐ橋渡し処理)。
https://scrapbox.io/files/6a11ba2065e24daf8cb1abd7.svg
WebGL版とWebGPU版の違い
左が WebGL版(1 canvas を共有)、右が WebGPU版(2 canvas を重ねる)です。
https://scrapbox.io/files/6a1bf6a965e24daf8cc56874.svg
WebGL版のコードでは、canvas は1つだけ(#canvas)です。Babylon が作った WebGL コンテキスト engine._gl を取り出し、それをそのまま context.init(gl) で Effekseer に渡しています。つまり同じ1枚の canvas・同じ GL コンテキストに、Babylon と Effekseer が順番に描き込む構造です。
一方 WebGPU版では canvas が2枚あります。「canvas-babylon」(Babylon用)と「canvas」(Effekseer用)です。Babylon は WebGPUEngine で自分の canvas に描画し、Effekseer は effekseerCanvas.getContext("webgpu") で取得した別の WebGPU コンテキストに独立して描画します。2枚の canvas を CSS で重ねることで、見た目上1つの画面に合成されています。