WebGLパフォーマンス
WebGLは悪い評判があります:開発者はWebGLが遅く、複雑な3Dグラフィックスをレンダリングできないと仮定します。 多くの例がこれは真実ではないと示していますが、開発者の経験はこの考えを何度も強化しています。
WebGLコードを実行するハードウェアはブラウザ用に制限されていません。 では、なぜ開発者はWeb上で高速な3Dグラフィックスをレンダリングすることは不可能だと信じるのでしょうか?
この記事では、WebGLのパフォーマンスについて案内し、あなたもWeb上で高速な3Dレンダリングを達成できるようになります。
CPU vs GPU
3Dアプリケーションでは、一部のコードはCPUで実行され、他のコードはアクセラレートされたハードウェア、具体的にはGPUで実行されます。
WebGLは、Web上でグラフィックスアプリケーションを加速するためにGPUを使用できるように設計されています。 したがって、WebGLはグラフィックスハードウェアに作業を送信し、結果を取得する関数として理解できます。
GPUのための作業を作成するコードはCPUで実行され、WebGL用にはJavaScriptでそれを制御します。
ブラウザのオーバーヘッド
ブラウザの目的の一つは、ユーザーを潜在的な悪意のあるWebサイトから守ることです。 そのため、WebサイトがJavaScriptを介して行うすべてのWebGL呼び出しの安全性を確認します。 また、Webサイトのコードを実行するプロセスを分離し、このプロセスとの間のすべての呼び出しを送信可能な形式に変換する必要があります。これを「マーシャリング」と呼びます。
マーシャリングとWebサイトのWebGL呼び出しの検証の両方が、ネイティブ環境での同じ呼び出しに比べてパフォーマンスコストを追加する作業を伴います。
WebGL呼び出しの回避
したがって、WebGLパフォーマンスを実現するためには、オーバーヘッドの高い呼び出しを回避すべきです。 特に高コストな呼び出しを簡単に把握するには、WebGLアプリケーションをプロファイルしてください。
以下はいくつかの特に高価な呼び出しです:
これらの呼び出しを避ける優れた方法は、WebGLの状態追跡を行い、WebGLアプリケーションの本番ビルドでエラーチェックを減らすことです。
描画呼び出しの回避
優れたWebGLパフォーマンスの秘密は、可能な限り描画呼び出しを減らすことです。描画呼び出しは、以下のWebGL関数のいずれかを使用する関数です:
- drawArrays()
- drawElements()
- drawArraysInstanced()
- drawElementsInstanced()
- drawBuffers()
- drawRangeElements()
これを達成する方法は多くあります。例えば、多くのオブジェクトを一度に描画する単一の関数呼び出しを使用するか、同じオブジェクトを描画するために関数を何度も呼び出すのではなく、 インスタンシングを使用して同じメッシュを大量にレンダリングすることや、同じシェーダーを使用したWEBGL_multi_drawを活用して異なるオブジェクトを多数描画することです。
3Dエンジンはしばしば「バッチ処理」と呼ばれる機能を持ち、多くの呼び出しを単一のWebGL呼び出しに結合します。Wonderland Engineはこれを極端なレベルに引き上げ、数万の動的オブジェクトが10未満の描画呼び出しで自動的にレンダリングされます。
特にモバイルでのWebGLパフォーマンスは描画呼び出しに影響を受けます。
SafariでのWebGL
Safari(iOSとmacOSの両方)では、意外にも多くのオーバーヘッドが発生するWebGL呼び出しが追加されています。例えば:
Safari用に最適化する際は、Uniform Buffersの使用に特に注意を払ってください。
JavaScript
ブラウザAPI、例えばWebGLと連携するために使用される言語はJavaScriptです。JavaScriptでの主なパフォーマンスの原因はガベージコレクションであり、不要になったメモリを自動的に見つけて削除します。
ガベージコレクションのプロセスは、WebGLアプリケーションのパフォーマンスを予測不可能で信頼できないものにする可能性があります。発生するタイミングを制御できないためです。その結果、レンダリング中のカクつきを引き起こし、パフォーマンスが悪いという印象を与えることがありますが、コード自体は非常に最適化されています。
安定したフレームレートを実現するためには、ガーベージのないJavaScriptを書く厳格なアプローチを取ってください。
iOS Safariとメモリ
Safariで正常に動作するWebGLアプリは稀です。SafariでのWebGLパフォーマンスは、また別の課題を提示します。Safari用に最適化する方法について、私たちはブログ記事全体を書きました。
メモリ制限
iOSでは別の課題に直面します:ブラウザタブは非常に限られたメモリを持っています。特に古いiPhoneハードウェアでは。 メモリ制限を超えると、タブがリロードされたりフリーズする可能性があります。iPhoneは統一メモリを使用しているため、CPUとGPUのRAMが共有され、テクスチャとバッファデータ、JavaScriptやWebAssemblyのメモリはすべて制限にカウントされます。