spryte 登場
debuff のゲームはすべて、ひとつのレンダラーを通して描画されています。これまでは @debuffjp/core の中にありましたが、今日から独立したライブラリ spryte になりました。MIT ライセンスで依存ライブラリはゼロ。debuff の有無に関係なく、どんなプロジェクトでも使えます。
npm install spryteimport { createRenderer } from "spryte";
const draw = createRenderer(canvas, { smooth: false }); // ピクセルアート
draw.resize(canvas.width, canvas.height);
function frame() {
draw.begin("#111", 320, 180, canvas.width / 320); // クリア色、論理サイズ、1 単位あたりのピクセル数
draw.sprite(hero, 160, 90, { rotation: 0.2, tint: "#cffb2d" });
draw.text("hello", 8, 8);
draw.end();
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);spryte とは
spryte はイミディエイトモードの 2D レンダラーです。表示オブジェクトでシーングラフを組み立てる必要はありません。毎フレーム、描きたいものを順番に描くだけで、spryte がそれをまとめて GPU に送ります。
- スプライト、図形、テキスト:
sprite、rect、circle、line、text(CSS フォントとビットマップフォントに対応)。変形、クリップ、色合い(tint)、アルファ、ブレンドモードも使えます。 - 一括描画:
draw.sprites()はFloat32Arrayに入った何千もの位置に 1 枚の画像を描きます。コピーごとのスケール、回転、色も指定できます。WebGL2 では配列をそのまま GPU に渡すので、スプライトごとの JavaScript 処理はありません。詳しくは draw.sprites でパーティクルと弾を描く をどうぞ。 - レンダーターゲットとシェーダー: オフスクリーン画像に描いてから、自作のフラグメントエフェクトを通して描画できます。詳しくは spryte でポストプロセス をどうぞ。
- WebGL2 と Canvas 2D フォールバック。 フォールバックは必要なブラウザでだけ読み込まれます。コンテキストロストにも対応済みです。
- 小さなアプリなら JavaScript は約 10 kB(brotli)です。
どれくらい速いのか
同じマシン、同じアセット、同じシミュレーションで PixiJS 8 と比べたベンチマークです。両者が同じピクセルを描いていることを確認したうえで計測しています。
| spryte | PixiJS 8 | ||
|---|---|---|---|
| 20 万パーティクル、全プロパティが毎フレーム変化 | 7.7 ms | 28.9 ms(ParticleContainer) | 3.8 倍速い |
| 回転・着色した 5 万スプライト、1 枚ずつ呼び出し | 9.8 ms | 32.3 ms(Sprite) | 3.3 倍速い |
| 20 万スプライト、位置のみ、一括 | 4.4 ms | 8.9 ms(ParticleContainer) | 2.0 倍速い |
| 起動時の JavaScript | 10.1 kB | 87.8 kB | 約 9 分の 1 |
これはデスクトップ向けノート PC 1 台での結果です。最初に試したスマートフォン(iPhone)では、一般的なスプライトとパーティクルでは差が保たれましたが、位置のみの一括描画では差がなくなりました。計測方法と注意点は ベンチマークページ にまとめています。ここまでの道のりは、撤回せざるを得なかった数字も含めて、リサーチ記事 spryte が PixiJS より 2〜3.8 倍速くなるまで で紹介しています。
あわせて、どんな 2D Web レンダラーでも参加できるオープンなベンチマーク 2dbench も始めました。コミュニティの結果 にまだ載っていないスマートフォン、タブレット、ノート PC をお持ちなら、ブラウザで実行 して、数タップで結果を送れます。
なぜ別ライブラリにしたのか
- debuff のゲームにとっては何も変わりません。
@debuffjp/coreは spryte に依存して再エクスポートしているので、シーン内のdraw.sprite()はこれまでどおり動きます。しかも新機能(draw.sprites、レンダーターゲット、シェーダー)もそのまま使えます。 - それ以外の人にとっては、単体で使えるようになります。 エディタ、ビジュアライゼーション、別のエンジン、素の canvas アプリでも、ゲームフレームワークを丸ごと入れずに spryte だけを使えます。
- 自分たちに正直でいられます。 単体のレンダラーは、自分のベンチマークとテストだけで評価されます。spryte の高速パスは、実際の GPU 上でシンプルなパスとピクセル単位で照合しています。0.1.1 の前には粗探し前提のレビューも受け、見つかった 6 つのバグを修正しました。
これから
データに載る端末を増やすこと(特にミドルレンジの Android)、2dbench のシーンを増やすこと(タイルマップ、テキスト、オブジェクトの頻繁な生成と破棄)、そして実際のゲームが必要とする機能を足していくことです。コード、ドキュメント、issue は github.com/debuffjp/spryte に、API リファレンスは このサイト にあります。