本文へスキップ

canvas から WebGPU へ:ブラウザがゲームプラットフォームになるまで ​

Flash が終わったとき、ブラウザゲームに代わりのプラグインは必要ありませんでした。ブラウザそのものが、少しずつプラグインになっていたからです。15年ほどのあいだに、ひと握りのオープンな API が、文書を表示するためのソフトをゲームをリリースできる場所へと変えました。

この記事では、それらの API を登場した順にたどり、ゲームを作る人にとって何が変わったのかを見ていきます。(それ以前のプラグインの時代については、Flash ゲームとポータルの時代をどうぞ)

ざっくり年表 ​

  1. 2004Apple が WebKit に canvas 要素を追加。最初は Dashboard ウィジェットと Safari のためでした。ほかのブラウザも続き、HTML5 の一部になります。
  2. 2010Mozilla が requestAnimationFrame を提案。タイマーで当て推量するのではなく、ディスプレイに合わせて描画する方法です。
  3. 2011Khronos が WebGL 1.0 をリリースし、OpenGL ES 2.0 風の GPU 描画がページにやってきます。
  4. 2013Mozilla が asm.js を発表。Epic と Mozilla が、プラグインなしで Firefox 上で動く Unreal Engine 3 を披露。
  5. 2014W3C が HTML5 を勧告として公開。
  6. 2017WebAssembly が主要ブラウザすべてで利用可能に。OpenGL ES 3.0 ベースの WebGL 2 が Chrome と Firefox に搭載。
  7. 2021Safari 15 が WebGL 2 に対応し、ようやく主要ブラウザすべてで動くように。
  8. 2023Chrome 113 が、ウェブのために設計されたモダンな GPU API である WebGPU を搭載。

出典:Canvas element、MDN の requestAnimationFrame、WebGL、asm.js、HTML5、WebAssembly、WebGPU。

canvas:描く場所ができた ​

canvas 以前、素の HTML での「ゲーム」といえば、<div> や画像をページ上で動かすことでした。カードゲームならそれで足りましたが、それ以上はほとんど無理でした。canvas はページに、JavaScript で描き込めるビットマップを与えました。矩形、画像、テキストを、毎フレーム描き直すのです。

2D ゲームは今もこのモデルを使っています。Canvas 2D は今でも一番安全なフォールバックでもあります。どのブラウザ、どのデバイスでも動くので、debuff は WebGL2 のレンダラーの後ろに Canvas 2D のレンダラーを控えさせています。

requestAnimationFrame:時間どおりに描く ​

初期の canvas ゲームは setInterval でループを回し、16 ms のような数字を選んで祈っていました。タイマーはずれるし、裏のタブでも動き続けるし、画面が実際にいつ更新されるかも知りません。requestAnimationFrame は、次の再描画の直前に呼んでくれるよう、そしてタブが隠れたら止まるようにブラウザに頼む仕組みです。

小さな話に聞こえます。でも、ブラウザゲームがそもそも滑らかに感じられるのはこのおかげで、フレームのペースを今も測る価値があるのもこのためです。それが Myaku の仕事です。

WebGL:GPU がやってきた ​

Canvas 2D の描画はほとんどブラウザ任せで、何千ものスプライトを詰め込むと遅くなります。WebGL は、シェーダーと頂点バッファを通じて JavaScript から GPU を直接使えるようにしました。突然、ブラウザで何万ものスプライトを描き、ポストプロセスをかけ、3D を描画できるようになったのです。

そのまわりにライブラリが育ちました。PixiJS と Phaser はどちらも2013年に登場し、シェーダーを手書きしなくても 2D ゲームで WebGL を実用的に使えるようにしました(PixiJS、Phaser)。のちに WebGL 2 でインスタンシングや多くのテクスチャフォーマットが標準になりましたが、Safari の対応は2021年までかかったので、多くのエンジンは何年も WebGL 1 の経路を残していました。

サウンドと入力 ​

ゲームにはピクセル以外も必要です。<audio> 要素は音楽プレイヤー向けに作られていて、効果音にはタイミングが甘すぎました。Web Audio API は、ゲームに精密なスケジューリングができるまともなミキシンググラフを与えました(MDN)。Gamepad API でページからコントローラーを読めるようになり(MDN)、Pointer Events API はマウス、ペン、タッチをひとつにまとめました。

この時代のクセがひとつ、今も残っています。プレイヤーがページを操作するまで、ブラウザは音を鳴らしてくれません。だから Web ゲームの多くが「クリックしてプレイ」から始まるのです。

asm.js と WebAssembly:ほかの言語がやってくる ​

2013年、Mozilla は JavaScript の厳格なサブセットである asm.js に C や C++ からコンパイルでき、ネイティブに近い速度で動くことを示しました。人々の目を引いたのは、Firefox で動く Unreal Engine 3 のデモでした(出典)。

WebAssembly はそのアイデアをきちんとしたバイナリ形式にし、2017年に主要ブラウザすべてで使えるようになりました。Unity や Godot といったエンジンはこれを通じてウェブに書き出しますし、Flash ゲームを遊べる状態に保っているエミュレータの Ruffle もそうです。トレードオフはサイズです。WebAssembly にコンパイルされた大きなエンジンは、ゲーム本体を入れる前から数十メガバイトあることも多いです。すぐ遊べることを重視するなら、これは大問題です。

WebGPU:次の GPU API ​

WebGL は、今日の GPU よりずっと前に設計された API である OpenGL ES がベースです。WebGPU は Vulkan、Metal、Direct3D 12 といったモダンなネイティブ API を前提に設計され、コンピュートシェーダーも加わりました。Chrome が2023年に搭載し、ほかのブラウザも追いかけています(出典)。

ほとんどの 2D ゲームには今も WebGL2 で十分で、しかもほぼどこでも動きます。WebGPU が一番効いてくるのは、少なくとも今のところ、重い 3D と GPU コンピュートです。

合わせると何になるか ​

これらの API はどれも、プラグインやインストールが必要な理由をひとつずつ取り除いてきました。

  • 描画には canvas と WebGL。
  • 滑らかなタイミングには requestAnimationFrame。
  • サウンドと入力には Web Audio、Gamepad、Pointer Events。
  • ほかの言語で書かれたコードには WebAssembly。

その結果が、リンクから開けて、ほぼすべてのスマホとコンピュータで動くプラットフォームです。タダでは手に入らないのが、小さなダウンロードサイズです。そこは今もエンジン次第です。

debuff の立ち位置 ​

debuff は、このスタックの中で最も広く対応している層を狙っています。WebGL2 と Canvas 2D フォールバック、素の TypeScript、ダウンロードすべき WebAssembly のランタイムはなし。スターターゲームは brotli で約 19 kB で出荷されます。その上に、プラットフォームが与えてくれないものを足しています。決定的なテスト、リプレイ、ライブ調整できるパラメータ、そして一緒にゲームを遊んでくれるコーディングエージェントです。

bash
npm create debuff@latest my-game

歴史の話をもっと読むなら:Flash ゲームとポータルの時代とゲームジャムと小さなゲーム。