WebGLは、プラグインを入れずにブラウザ上でGPUを使い2D・3Dグラフィックスを描画するためのJavaScript APIです。この記事では、仕組みと対応ブラウザの確かめ方、三角形を描くコード(Chrome 155で動作確認済み)、WebGPUとの違いと2026年10月時点の対応状況、そしてUnityでWebGL(Unity 6以降の名称はWeb)ビルドを作って配信する手順と機能制限までを、Khronos Groupの仕様書とUnity公式マニュアルを根拠に解説します。
まとめ:WebGLの要点
- 正体:
<canvas>上でGPUを制御するJavaScript API。WebGL 1.0はOpenGL ES 2.0、WebGL 2.0はOpenGL ES 3.0がベースで、プラグイン不要で動く。 - 対応状況:WebGL 2.0はChrome 56・Firefox 51・Safari 15以降が対応し、Can I useの利用シェア換算で97.13%(2026年10月19日時点)。表示されないときはハードウェアアクセラレーションとGPUドライバを確認する。
- 後継WebGPU:Chrome・Edge、Windows版とApple Silicon Mac版のFirefox、Safari 26以降が対応。Linux版・Intel Mac版・Android版のFirefoxではまだ既定で使えず、WebGLはフォールバック先として当面必要。
- Unityで使う:Unity 6ではプラットフォーム名がWebGLから「Web」に変わった。出力はWebAssembly+JavaScriptで、既定の描画APIはWebGL 2。Unity 6.6でWebGPUが実験版を卒業したが、6.3 LTSでは実験版のまま。
- 配信の要点:圧縮の既定はgzip。BrotliはChromeとFirefoxがHTTPSでしかネイティブ展開しない。サーバーが
Content-Encodingを返せないならDecompression Fallbackを使う。
WebGLとは:ブラウザからGPUを動かすJavaScriptの描画API
WebGL 1.0と2.0の違いとOpenGL ESとの対応関係
WebGL(Web Graphics Library)は、非営利団体Khronos Groupが策定する、ブラウザ内でGPUアクセラレーションによるグラフィックスを描くためのJavaScript APIです。組み込み向けのグラフィックスAPIであるOpenGL ESをWebに移植したもので、WebGL 1.0仕様はOpenGL ES 2.0に、2017年4月に確定したWebGL 2.0仕様はOpenGL ES 3.0に準拠します。FlashやUnity Web Playerのようなプラグインを必要とせず、ブラウザの標準機能だけで動く点が最大の特徴です。
| 項目 | WebGL 1.0 | WebGL 2.0 |
|---|---|---|
| ベースの仕様 | OpenGL ES 2.0 | OpenGL ES 3.0 |
| シェーダー言語 | GLSL ES 1.00 | GLSL ES 3.00 |
| コンテキスト名 | webgl | webgl2 |
| 主な追加機能 | 拡張機能で個別に補う | 3Dテクスチャ・インスタンス描画・MRT |
WebGL 2.0ではVAO(頂点配列オブジェクト)やインスタンス描画、複数の描画先(MRT)が標準機能になり、1.0では拡張機能を個別に有効化していた処理をそのまま書けます。API一覧はMDNのWebGL2RenderingContextにあります。
canvasとシェーダーで描く仕組み:頂点からピクセルまでの4段階
描画先はHTMLの<canvas>要素です。canvas.getContext('webgl2')で取得したコンテキストから、頂点シェーダー(頂点の座標変換)とフラグメントシェーダー(ピクセルの色計算)という2種類のGPUプログラムをGLSLで書いて動かします。処理は、①頂点バッファにデータを入れる、②頂点シェーダーが各頂点の画面上の位置を決める、③GPUが三角形で塗る範囲のピクセルを割り出す、④フラグメントシェーダーが各ピクセルの色を返す、の4段階です。後述のコードもこの順に並んでいます。Unityでノードを組んで作るシェーダーも、最後はこの頂点・フラグメントの2段に変換されます。ノード側の作り方はUnity Shader Graphの使い方で扱っています。
WebGLでできること:ゲーム・3D製品ビューア・データ可視化
- ブラウザゲーム:インストール不要で遊べるWebゲーム。UnityやPhaserで作ったゲームのWeb版もWebGLで描かれる。
- 製品コンフィギュレータ・3Dビューア:家具や車をブラウザ上で回転・色替えして確認するEC向けの表現。
- データ可視化・地図:数万点規模の散布図や地理データを滑らかに描くダッシュボードや地図ライブラリ。
- インタラクティブな演出:スクロールに連動する背景アニメーションやパーティクル表現。
どれもGPUで多数の要素を毎フレーム描き直す処理です。数十個のボタンが動く程度のUIならCSSで足り、WebGLを持ち込むと保守の負担だけが増えます。
WebGLの対応ブラウザを確かめ、無効・表示されないときに直す手順
主要ブラウザのWebGL 2.0対応版とget.webgl.orgでの確認
Can I useのWebGL 2.0の表では、Chrome 56・Edge 79・Firefox 51・Safari 15(iOS Safariも15)以降が対応し、利用シェア換算の対応率は97.13%です(2026年10月19日取得)。Safariは長くWebGL 2.0に対応しておらず、WebKitのSafari 15の発表で対応しました。iOS 14以前の端末を対象に含めるなら、WebGL 1.0へのフォールバックを残します。
使っている環境で動くかどうかは、Khronosの確認ページで見るのが早道です。get.webgl.orgで回転する立方体が表示されればWebGL 1.0が、WebGL 2.0の確認ページで同様に表示されればWebGL 2.0が有効です。
JavaScriptでWebGL 2・WebGL 1の対応を判定するコード
サービスに組み込むときは、コード側で判定して分岐させます。次のコードは開発者ツールのConsoleに貼り付けて実行でき、使える版とドライバが返すバージョン文字列を表示します。
const c = document.createElement('canvas');
const gl2 = c.getContext('webgl2');
const gl1 = gl2 ? null : c.getContext('webgl');
const gl = gl2 || gl1;
if (!gl) {
console.log('WebGLは無効です(ハードウェアアクセラレーション設定を確認)');
} else {
console.log('利用できる版:', gl2 ? 'WebGL 2' : 'WebGL 1');
console.log('VERSION:', gl.getParameter(gl.VERSION));
console.log('GLSL:', gl.getParameter(gl.SHADING_LANGUAGE_VERSION));
console.log('最大テクスチャサイズ:', gl.getParameter(gl.MAX_TEXTURE_SIZE));
}
macOS版Chrome 155で実行するとVERSION: WebGL 2.0 (OpenGL ES 3.0 Chromium)と表示され、最大テクスチャサイズはGPU描画で16384、ソフトウェア描画(SwiftShader)で8192でした。この値は端末とドライバで変わるため、大きな画像をテクスチャにする実装では、値を見て縮小版に切り替えます。
WebGLが無効・表示されないときにブラウザとGPUを確認する順番
- ハードウェアアクセラレーションを有効にする:Chromeなら設定の「システム」で「グラフィック アクセラレーションが使用可能な場合は使用する」をオンにして再起動する。
- GPUの状態を見る:Chromeのアドレスバーに
chrome://gpuと入力し、WebGLとWebGL2の項目が「Hardware accelerated」になっているかを確認する。 - GPUドライバを更新する:古いドライバはブラウザのブロックリストに入り、WebGLが無効化されることがある。
- 拡張機能を切り分ける:拡張機能を外したシークレットウィンドウで開き、表示されるなら拡張機能側を疑う。
企業端末ではポリシーでアクセラレーションが止められていることがあり、リモートデスクトップや仮想マシン経由ではソフトウェア描画になって極端に遅くなります。
WebGLを動かす:コンテキスト取得からシェーダーで三角形を描くまで
GLSLの頂点・フラグメントシェーダーで三角形を1枚描くコード
図形を描くには、GLSLで書いたシェーダーをコンパイルしてプログラムにまとめ、頂点バッファを用意してgl.drawArraysを呼びます。次のコードをHTMLファイル1枚に保存してブラウザで開くと、濃紺(ほぼ黒)の背景に青い三角形を描きます。Chrome 155(macOS)でファイルを直接開き、表示されることを確認しました。
<canvas id="gl" width="640" height="360"></canvas>
<script>
const canvas = document.getElementById('gl');
const gl = canvas.getContext('webgl2');
// ① シェーダーのソース(GLSL ES 3.00)
const vsSource = `#version 300 es
in vec2 aPos;
void main() { gl_Position = vec4(aPos, 0.0, 1.0); }`;
const fsSource = `#version 300 es
precision mediump float;
out vec4 outColor;
void main() { outColor = vec4(0.2, 0.6, 1.0, 1.0); }`;
// ② コンパイルとリンク(失敗時はログを例外で出す)
function compile(type, src) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) throw new Error(gl.getShaderInfoLog(s));
return s;
}
const prog = gl.createProgram();
gl.attachShader(prog, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(prog, compile(gl.FRAGMENT_SHADER, fsSource));
gl.linkProgram(prog);
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) throw new Error(gl.getProgramInfoLog(prog));
// ③ 頂点バッファ(クリップ座標 -1〜1 で3頂点)
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.6, -0.6, -0.5, 0.6, -0.5]), gl.STATIC_DRAW);
const loc = gl.getAttribLocation(prog, 'aPos');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
// ④ 描画
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.1, 0.1, 0.15, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(prog);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
三角形1枚でも40行前後かかり、回転・立体・質感を足すと行列計算や深度バッファ、ライティングが加わってさらに膨らみます。
実行して分かった3つのつまずき:#version行・描画バッファ・コンテキストロスト
上のコードを少しずつ変えてChrome 155で動かすと、初学者が詰まりやすい挙動を3つ再現できました。
#version 300 esの前に改行を入れるとコンパイルに失敗する:テンプレート文字列の`の直後で改行すると、#version directive must occur on the first line of the shaderというエラーがgetShaderInfoLogに出る。- 描画後に別のタイミングで
readPixelsすると0が返る:既定のpreserveDrawingBuffer: falseでは、画面への表示が済むと描画バッファが消える。三角形の中心を後から読むと[0,0,0,0]、getContext('webgl2', { preserveDrawingBuffer: true })にすると[51,153,255,255]が返った。スクリーンショット機能を作るなら、描画と同じフレームで読むか、このオプションを付ける。 webglcontextlostでpreventDefault()を呼ばないと復帰しない:GPUのリセットなどでコンテキストが失われたとき、ハンドラーでpreventDefault()を呼んだ場合だけwebglcontextrestoredが届き、再初期化できた。呼ばない場合はrestoreContext()を実行しても復帰イベントが来なかった。
canvas.addEventListener('webglcontextlost', (e) => {
e.preventDefault(); // これを呼ばないと restored が届かない
});
canvas.addEventListener('webglcontextrestored', () => {
init(); // シェーダー・バッファ・テクスチャを作り直す
});
素のWebGLかThree.js・Babylon.js・PixiJSかを決める基準
| 選択肢 | 得意分野 | 選ぶ場面 |
|---|---|---|
| Three.js | 汎用3D | 3Dシーン・glTF表示 |
| Babylon.js | ゲーム・3D | 物理・エディタも使う |
| PixiJS | 2D | 2D演出・大量スプライト |
| 素のWebGL | 学習・特殊処理 | 依存ゼロ・独自パイプライン |
3Dシーンを組むなら第一候補はThree.jsで、上の三角形と同じことが十数行で書け、glTFモデルも標準のローダーで読み込めます。導入手順はThree.jsの導入手順とglTF表示・バンドルサイズの実測にまとめました。2D中心ならWebGL/WebGPUで動く2D描画エンジンPixiJSが扱いやすい選択です。素のWebGLを選ぶのは、ライブラリの容量を削りたい場合か、独自のシェーダーパイプラインを組む研究・可視化に限られます。
WebGLとWebGPUの違い:2026年10月の対応状況と移行の判断
WebGPUはW3CのWebGPU仕様で定義される新しいAPIで、GPUをより低レベルに扱い、描画だけでなくコンピュートシェーダーによる汎用計算も実行できます。シェーダー言語はGLSLではなくWGSLです。WebGLはOpenGL ES由来、WebGPUはDirect3D 12・Metal・Vulkanといった現行のネイティブAPIの上に作られている点が根本の違いです。
WebGPUの対応ブラウザ一覧(2026年10月時点)
| ブラウザ | 既定で使える範囲 | 根拠 |
|---|---|---|
| Chrome・Edge | 113以降(Windows・macOS・ChromeOS) | web.dev |
| Chrome(Linux) | 144から段階提供(Intel Gen12以降など) | Chrome 144 |
| Chrome(Android) | 121以降・Android 12以上の一部GPU | Chrome 121 |
| Firefox(Windows) | 141以降 | Firefox 141 |
| Firefox(Apple Silicon Mac) | 145以降(145・146はmacOS 26のみ、147以降は全macOS) | Firefox 147 |
| Firefox(Linux・Intel Mac) | Nightly版のみ | MDN |
| Firefox(Android) | 既定で無効 | Can I use |
| Safari | 26以降(macOS Tahoe 26・iOS 26以降など) | WebKit |
WebGL 2.0の対応率97.13%に対し、Can I useの同じ日のWebGPUは完全対応85.8%・部分対応3.66%でした。約1割の利用者はWebGPUで描けないため、不特定多数に見せるページでWebGLを外すのは時期尚早です。GPUで汎用計算をしたい案件(ブラウザ内の機械学習推論、数十万粒子の物理計算)はWebGPUを主に据え、幅広い端末で確実に表示したい製品ビューアや広告演出はWebGLで作ります。RustからWebGPUを扱うならRustでWebGPUを扱うwgpuの仕組みと最小サンプルが参考になります。
WebGPUを先に試しWebGLへフォールバックする判定コード
navigator.gpuが存在しても、GPUがブロックされているとrequestAdapter()はnullを返します。アダプタの取得まで確かめてから判定します。
async function detectGraphicsApi() {
if (navigator.gpu) {
const adapter = await navigator.gpu.requestAdapter();
if (adapter) return 'webgpu';
}
const c = document.createElement('canvas');
if (c.getContext('webgl2')) return 'webgl2';
if (c.getContext('webgl')) return 'webgl1';
return 'none'; // 静止画などの代替表示へ
}
detectGraphicsApi().then((api) => {
console.log('使用する描画API:', api);
});
ヘッドレスモードのChrome 155では、GPU描画でwebgpu、SwiftShaderでのソフトウェア描画でwebgl2が返り、--disable-webglと--disable-3d-apisを付けてWebGLを止めてもwebgpuが返りました。2つは別々に無効化されうるので、両方を判定します。Three.jsやBabylon.jsはこの結果でレンダラーを切り替えられます。
UnityでWebGLビルドを作る手順:Unity 6のWebプラットフォーム
Unity WebGLの仕組みとUnity 6での名称変更
UnityはWeb向けにビルドすると、C#のゲームロジックをIL2CPP経由でWebAssemblyへ変換し、描画をWebGL 2(設定によりWebGPU)でブラウザに出します。WebAssemblyの仕組みはWebAssemblyのJavaScript連携とMemory・Table操作で扱っています。
Unity 6ではプラットフォーム名が「WebGL」から「Web」に変わりました。Unity 6の新機能一覧には「Web platform (previously WebGL)」とあり、同じ版でモバイルブラウザにも対応しています。メニューで「WebGL」が見当たらないときは「Web」を探します。Unity 6の他の変更点はUnityの日本語化とUnity 6の新機能に整理しました。
Web Build Supportの追加からビルドまでの4ステップ
- モジュールを追加する:Unity Hubの「インストール」で対象バージョンの歯車から「モジュールを加える」を選び、Web Build Support(Unity 6より前はWebGL Build Support)にチェックを入れる。
- プラットフォームを切り替える:File > Build Profilesを開き、PlatformsからWebを選んで「Switch Platform」を押す(Unity 6より前はFile > Build Settings)。
- Player Settingsを決める:Resolution and PresentationでWeb Template(Default/Minimal/PWA)を、Publishing SettingsでCompression FormatとDecompression Fallbackを選ぶ。Build ProfilesのCode Optimizationは既定が「Shorter Build Time」なので、公開用は「Runtime Speed with LTO」か、モバイル向けに容量を優先する「Disk Size with LTO」へ切り替える。Unity 6.6では容量最優先の「Maximum Size Reduction(with LTO)」も選べる。
- ビルドする:出力先を指定すると、
index.html、Buildフォルダ(.loader.js・.framework.js・.wasm・.data)、TemplateDataフォルダができる。ファイルの役割はマニュアルのWeb Build folderに一覧があります。
2026年10月19日時点の最新は、推奨版のUnity 6.6(6000.6.6f1、10月15日公開)とLTSのUnity 6.3(6000.3.26f1、10月8日公開)です。長期運用するゲームはLTSに置くのが基本で、6.3 LTSの変更点はUnity 6.3 LTSの新機能と変更点で確認できます。
Unity 6.6でWebビルドに加わった主な変更:WebGPU正式化とWebAssembly64
Unity 6.6の新機能一覧には、Web向けの変更として次の項目が並んでいます(ほかにWebGPU Device Filtering AssetとWebGPU互換モードへの自動フォールバックも追加)。ランタイムの小型化は最適化の節に載っています。
- WebGPUが実験版を卒業:6.3と6.5のマニュアルの「WebGPU (Experimental)」表記が6.6で外れた。WebGL 2でできないコンピュートシェーダーやVFX Graphが使える。
- WebAssembly64:64bitを選ぶとメモリ上限が4GBから16GBに上がる。読み込み時間を重視する用途には非推奨で、Safariは非対応。
- Progressive Asset Loading:起動時に全アセットを落とさず、シーンごとに読み込む。有効にするとName Files As HashesとDecompression Fallbackは使えなくなる。
- ランタイムの小型化:Code Optimizationに「Maximum Size Reduction」が加わった。
WebGPUは自動では有効になりません。マニュアルのWebGPUの有効化手順のとおり、Player SettingsのOther SettingsでAuto Graphics APIを外し、+からWebGPUを追加して一覧の先頭へドラッグします。WebGL 2を一覧に残せば、WebGPUが使えないブラウザでWebGL 2に切り替わります。WebGPU版はlocalhostかHTTPSでしか動かず、Texture2D.GetPixelsなどの同期読み出しはAsyncGPUReadbackへの置き換えが要ります。VFX Graphを使う場合の設定はUnity VFX Graphの使い方(URP・WebGPU対応)で扱っています。
Unity WebGLを公開・配信する設定:圧縮・サーバー・公開先
gzipとBrotliの選び方とDecompression Fallback
Unityの配信マニュアルによると、Compression Formatの既定はgzipで、HTTPとHTTPSのどちらでも全ブラウザがネイティブに展開できます。Brotliはgzipより小さくなる代わりにビルドが遅く、ChromeとFirefoxはHTTPSでしかネイティブ展開しません。社内の検証サーバーがHTTPのままならgzipのままにしておきます。
どちらの圧縮でも、サーバーがContent-Encodingヘッダーを返す必要があります。ヘッダーを設定できないホスティングではDecompression Fallbackを有効にすると、展開用のJavaScriptがローダーに入って動きます(ファイル名に.unitywebが付き、読み込みは遅くなります)。
NginxでBrotli圧縮ファイルにContent-Encodingを付ける設定
Unity 6.6のNginx向け設定マニュアルに沿うと、Brotliビルドでは既存のlocationの中に次の3ブロックを足します。
# Brotli圧縮済みのdata・symbols.json
location ~ .+\.(data|symbols\.json)\.br$ {
gzip off;
add_header Content-Encoding br;
default_type application/octet-stream;
}
# Brotli圧縮済みのJavaScript
location ~ .+\.js\.br$ {
gzip off;
add_header Content-Encoding br;
default_type application/javascript;
}
# Brotli圧縮済みのWebAssembly(application/wasmでストリーミングコンパイルが効く)
location ~ .+\.wasm\.br$ {
gzip off;
add_header Content-Encoding br;
default_type application/wasm;
}
gzip offは二重圧縮を防ぐ指定です。gzipビルドなら拡張子を.gz、ヘッダーをContent-Encoding gzipに置き換え、data・symbols.jsonのブロックだけはdefault_type application/gzip;にします。
Webサーバー経由のローカル確認とファイル直開きで動かない理由
Unityのマニュアルは、ブラウザがfile://からのスクリプト読み込みを制限するため、index.htmlをダブルクリックで開いても動かないと説明しています。手元の確認はBuild Profilesの「Build And Run」を使うか、出力フォルダで簡易サーバーを立てます。
python3 -m http.server 8000
Python 3.14のhttp.serverで確かめると、.wasmにはapplication/wasmを返す一方、.brにはContent-Encodingを付けませんでした。圧縮ビルドはこの方法では起動しないので、圧縮を無効にするかDecompression Fallbackを有効にして確認します。
公開先の選び方:Unity Play・静的ホスティング・自社サーバー
- Unity Play:Unityが運営する公開先。WebGL Publisherパッケージから公開でき、試作の共有に向く。
- 静的ホスティング(GitHub Pagesなど):ヘッダーを細かく決められないサービスではDecompression Fallbackか圧縮無効で出す。
- 自社サーバー・CDN:上のNginx設定でネイティブ展開でき、起動が最も速い。製品版はこれ。
重い3Dをブラウザで動かさず、クラウドのGPUで描いて映像だけを配信する方法もあります。その場合はUnity Render Streamingの使い方が候補です。
Unity WebGLの対応ブラウザ・機能制限と頻出エラー
Unity Webビルドの対応ブラウザと動かない機能
Unity 6.6のブラウザ互換性ページでは、WebGL 2に対応し、64bitでWebAssemblyを動かせるブラウザが条件です。デスクトップはChrome・Firefox・Edge(Windows・macOS・Linux)とmacOSのSafari、モバイルはiOS Safari 15以降とAndroidのChrome 58以降が対象になっています。
技術的な制限のページには、ネイティブ版と同じつもりで作ると動かない機能が並んでいます。
- C#のスレッド:WebAssemblyにマルチスレッドのガベージコレクションが無いため使えない。並列化はBurstでコンパイルしたC#ジョブで行う。
- ソケット通信:IPソケットへの直接アクセス、
System.Netのクラス、UnityEngine.Pingは使えない。HTTP通信はWeb networkingのとおりUnityWebRequest(ブラウザのFetch APIで動き、別ドメインへはCORSの許可が要る)、対戦通信はNetcodeパッケージで組む。 - 物理演算の再現性:WebAssemblyは極小値をゼロに丸めないため、エディターや他プラットフォームと結果が少しずつずれる。
Unity WebGLで頻出するビルドエラーと起動失敗の対処
- 「An exception has occurred, but exception handling has been disabled in this build.」:Web Player SettingsのEnable ExceptionsがNoneのビルドで例外が起きると出る。既定の「Explicitly Thrown Exceptions Only」でもNull参照や配列の範囲外は捕捉されないため、原因を追うときだけ「Full With Stacktrace」にしてビルドし直し、ブラウザのConsoleでスタックトレースを読む。性能とメモリを食うので本番では戻す。
- 「Unable to parse …」で始まる展開エラー:サーバーが
Content-Encoding: brを返していない。前述のNginx設定を入れるか、Decompression Fallbackを有効にする。 - 画面が真っ黒のまま起動しない:
index.htmlの直開きが原因であることが多い。ローカルサーバー経由で開く。 - メモリ不足で落ちる:Maximum Memory Sizeの既定は2048MB。テクスチャ圧縮(モバイルはASTCかETC2)とアセットの軽量化を先に行い、上限を上げるのは最後にする。
WebGLの制限と代替手段:モバイル性能とブロックリストへの備え
WebGLがモバイルで重くなる原因と描画解像度の上限設定
モバイルではドローコール数とテクスチャ容量がそのままフレームレートに響くため、バッチングとインスタンス描画で描画回数を減らします。見落としやすいのがdevicePixelRatioで、高解像度のスマートフォンで物理解像度のまま描くと塗るピクセル数が数倍になります。次のコードは倍率を2で頭打ちにします。
const MAX_DPR = 2; // 描画解像度の上限
function resize() {
const dpr = Math.min(window.devicePixelRatio || 1, MAX_DPR);
const w = Math.round(canvas.clientWidth * dpr);
const h = Math.round(canvas.clientHeight * dpr);
if (canvas.width !== w || canvas.height !== h) {
canvas.width = w;
canvas.height = h;
gl.viewport(0, 0, w, h);
}
}
new ResizeObserver(resize).observe(canvas);
resize();
Chrome 155で端末の倍率を3にして表示幅384×高さ300pxのcanvasに適用すると、描画バッファは1152×900ではなく768×600になりました。塗るピクセル数は約44%に減ります。
GPUブロックリストで描画されない環境への代替表示
ブラウザはGPUドライバの不具合や脆弱性を避けるため、危険な組み合わせをブロックリストで無効化します。Chromeではchrome://gpuの「Problems Detected」欄に、適用された回避策や無効化された機能が並びます。その環境ではWebGLが使えないため、前述の判定コードでnoneが返ったら静止画や動画、CSS表現に切り替えます。より高度なGPU計算が必要ならWebGPU、端末に依存せず重い3Dを見せたいならクラウドレンダリング、AR・VRをWebで動かすならWebXRのデモ・サンプル集と対応ブラウザ一覧で紹介しているWebXRが選択肢になります。
WebGLを採用する条件と見送る場面:3D表現を発注する前の判断基準
- WebGLを採用する条件:インストールを求めずURL1本で体験させたい、対象端末が幅広い(スマートフォン中心を含む)、表現が製品ビューア・データ可視化・軽量ゲームの範囲に収まる。3つがそろえばThree.jsやPixiJS経由のWebGLが第一候補。
- Unity WebGLを選ぶ条件:同じゲームをiOS・Androidアプリとしても出す予定があり、ブラウザ版を体験版や配布導線に位置付ける場合。1つのプロジェクトから複数プラットフォームへ出せる利点が、ダウンロード容量の大きさを上回る。
- 見送る場面:初回表示の速さが売上に直結するECのトップページ、低価格のAndroid端末が主な利用者層、数百MB級のアセットを扱う重いゲーム。前の2つはCSSアニメーションや動画で代替し、最後はネイティブアプリかクラウドレンダリングを選ぶ。
迷うのは「Webで出すか、アプリで出すか」が決まっていない段階です。一創ではゲームアプリ開発として、Unityでのアプリ開発とWeb版の同時展開を含めて企画段階から相談を受けています。端末要件と配信方法を先に決めると、WebGLを使うかどうかの判断も早くなります。
よくある質問
WebGLを有効にするにはどうすればよいですか?
主要ブラウザは初期状態で有効です。表示されない場合は、ハードウェアアクセラレーションをオンにし、chrome://gpuで「Hardware accelerated」か確かめ、GPUドライバを更新します。
WebGLに対応しているブラウザはどれですか?
WebGL 2.0はChrome 56・Edge 79・Firefox 51・Safari 15以降が対応し、2026年10月時点の対応率は97.13%です。
UnityにWebGLを入れるにはどうすればよいですか?
Unity Hubで対象バージョンの歯車から「モジュールを加える」を開き、Web Build Support(Unity 6より前はWebGL Build Support)を追加します。その後File > Build ProfilesでWebを選び、Switch Platformを実行するとWeb向けにビルドできます。
「Unity WebGL Player」と表示されるページは何ですか?
UnityでWeb向けにビルドされたゲームやアプリのページです。Unity 2019.4のテンプレート解説に載っている最小テンプレートは、ページのタイトルを「Unity WebGL Player | 製品名」の形にしており、このタイトルのまま公開されたゲームが多くあります。プラグインが必要だった旧Unity Web Playerとは別物で、インストールなしにブラウザで動きます。
WebGLとWebGPUはどちらを使うべきですか?
幅広い端末で確実に動かすならWebGL、コンピュートシェーダーや汎用計算を使うならWebGPUです。WebGPUを主にする場合もWebGLへのフォールバックを用意します。