Unityで有料アセットのコーギーエンジンを使って自作ゲームをwebGLビルドで出力したものを圧倒的に軽くしてユーザー満足度を高める為の方法を調べた時のつぶやきをまとめただけの記事
調査段階なのでまとまりも悪くて関係の無いトピックスも入っていたりして間違っていることもあるかも知れない。後日整理する予定
webGLビルド時に行う軽量化方法
モバイル向けのビルド時に行う軽量化方法
影を無くす
テクスチャ圧縮タイプをASTCにする
アンチエイリアスをやめる
カメラの機能でポストプロセッシングを無効にする
ゲームが重たくなる処理の一覧
スキンドメッシュレンダー
ポストプロセッシング
アルファブレンディング
デバイスの高解像度
影の描写
重たい処理としては、スキンドメッシュレンダー、ポストプロセッシング、アルファブレンディング、高解像度があります。本当に必要かどうかを検討して不要なら影やカメラ制御のように、パフォーマンスを得るために、ゲームシーンからカットしたり、最適化しても問題ないかを検討するのが良さそうです。
ゲームの軽量化につながる為の処置として、簡単なものは、影の廃止、ポストプロセスの廃止、マテリアルの統合、テクスチャアトラスの使用、メッシュの結合、テクスチャ圧縮形式の変更、サイズを減らす等がある。品質は下がるがFPSは良くなると思われるのでバランスをみて調整したい。
マテリアルをオブジェクトあたりで減らす事がパフォーマンス改善につながるのは、SetPassCallの呼び出し回数の削減に繋がっている為だと思われる。有料アセットのメッシュベイカーなどを利用すると、この辺りの仕組みをうまく最適化するので、ドローコール処理が軽くなり、軽量化につながる
バッチの回数はStatsの画面から確認する事ができ、Batchesがバッチ処理の回数を表して各バッチごとにSetPass Call→DrawCallの順に呼ばれレンダリング処理を行う。1バッチに1回のドローコール処理があるがマテリアルの指示がない場合はSetPassCallが省略
ゲームのパフォーマンスを向上させるにはドローコールを減らす必要があります。ドローコールはオブジェクトやテクスチャをGPUがレンダリングする時に呼ばれます。ドローコールはCPUからAPIを使って呼ばれるので、ドローコールが多くなればなるほどゲームのパフォーマンスが落ちます。
静的バッチ処理は、動かない(静的な)オブジェクトをひとまとめの大きなメッシュと結合してレンダリングする。動的バッチ処理は、今のところよく分からない…小さいメッシュ用に頂点をひとまとめにして描画するらしい欠点もある。静的はメモリとストレージを消費し、動的はCPUを消費する。
ドローコールはUnityでは一回の処理としてまとめる機能がある。ドローコールバッチング機能によってドローコール負荷をひとまとめにして、ゲームのパフォーマンスが出るようにしている。バッチ処理には二種類あって、動的バッチ処理と静的バッチ処理がある。
OpenGLやDirectXはグラフィックスAPIというソフトウェアに描画命令を行うアプリケーション・プログラミング・インタフェースの名称で、描画命令はCPU→グラフィックスAPIに指示が行われている。ドローコールが重たい時=CPUに負荷がかかる。ではドローコール表示はどうするか
Unityのスプライトアトラスというアセットを使って複数のテクスチャを1つのテクスチャに統合することが出来るため、この統合されたテクスチャを参照することでUnityのドローコールを抑える事ができ、プロジェクトのパフォーマンスの改善に有効かも知れません。
パーティクルシステムは小さな2D画像からそれらをアニメーションさせることで様々な表現をすることができる、(流体、雲、炎など)しかも大量のオブジェクトに見えて1つの塊扱いなのでWebGLのドローコールが少なくリッチな表現をするのに都合の良い仕組みだった様子(知らなかったよ…)
webGLでモバイルの負荷が高まる理由としてはドローコール回数が大きく影響していて、処理速度や消費電力量にも影響する。ドローコール回数を減らすためには、シーン内のオブジェクト数を減らすこととオブジェクトを構成するマテリアル数も減らすのが良いらしい。1オブジェクトにつき1マテリアルが良い
シーン中のUI CameraオブジェクトのInput Managerコンポーネントの設定にMobileかDesktopかの判定を自動で行うパラメータがあり、そこでforcedで強制的にモバイル指定を行うと、webgl出力でもUIカメラ配下のジョイスティックやボタンを活性化できます
WebGL2.0からはGeometry InstancingとMultiple Render Targetsという機能によって、一度の描画命令で、複数のオブジェクトやテクスチャに対して描画する事が従来のWebGL1.0と比べて高速に出来るようになったので、大量のオブジェクトを描画をしてもフレームレートを維持しやすくなったらしい。機能を使うには対応しているGPUは必須のようだ。
webGL2.0が使えると何が良いかというと、ドローコール回数を押さえて、同じメッシュオブジェクトの座標計算や拡大縮小などの指示をマルチタスクで処理できるので複数の処理が早いようだ。ジオメトリなんだっけ…使える機能が増えた事によって表現技術もwebGL1.0の頃よりも充実している
webGLについて調べていたら、webGL1.0と2.0の違いも分かっていなかった事が分かったのだけれど、どのブラウザバージョンがWebGL2.0に対応しているのか超絶分かりやすい記事を見つけたので全力でお知らせ。大抵は既にwebGL2.0caniuse.com/webgl2
スマホでも1分かからないくらいで読み込めるようになったみたいなので、今度はモバイル操作が出来るように修正を加えていく。壁張り付きやダッシュはモバイルとの相性が悪そうなので廃止を検討したい。
2019から2021.3LTSに変更したらWebGLのビルドサイズが激減したのか気になって調べたら、WebGLコンパイラツールのemscriptenがUnity2021.2でバージョンアップしversion2.0.19になった事の影響が大きいみたい。サイズ、時間、メモリ効率改善。
Unityエンジン2021.2で追加のWebGLの新機能で圧縮オーディオや圧縮テクスチャフォーマットサポートが追加された事も軽くなった要因なのかも知れない。まだ確実に調べきれていないけど、公式のドキュメントだからとりあえず2021.3LTSに上げてビルドすると軽くなりました。
UnityのWebGLビルドというウェブブラウザで遊べるようにゲームを出力できる設定があるのだけれど、そのパラメーター指定ではテクスチャ圧縮タイプは3種類あって、DXTとETC2とASTCがあり、ビルド設定画面で指定する形になります。ETC2よりもASTCの方が新しい形式の様子。
WebGLのTexture圧縮タイプを変更すれば、大きなサイズ変化が起こるのだろうと想像していたけれど、DXTもASTCもETC2もあまり変化が無かった。事前にテクスチャのサイズ自体を小さくしてしまっていると、もしかすると影響が少ないのだろうか?ビルド時間は断トツでDXTが早い
ビルド画面でCode Optimizationのパラメーターの初期値はSpeedとなっているが、Sizeに変更すると、サイズの縮小を目的としたビルドを行うことが出来るので、モバイル用で読み込みを拒否した場合の大規模ビルドに適しているらしいので、デフォルトのまま出力が重たい人試して
おそらく2021.2で追加されたWebGLの新機能で圧縮オーディオや圧縮テクスチャフォーマットサポートが追加された事も軽くなった要因なのかも知れない。まだ確実に調べきれていないけど、公式のドキュメントだからとりあえず2021.3LTSに上げてビルドすると軽くなってハッピーになれる
Unity2021.3LTSに変更したらWebGLのビルドサイズが激減したか気になって調べたらWebGLコンパイラツールのemscriptenがUnity2021.2でバージョンアップしてversion2.0.19になった事の影響が大きく、サイズ、時間、メモリ効率に改善が見られる
Unityのパフォーマンスを判断するとき、ドローコールとセットパスコールをUnity側でひとまとめにして、最適化した回数はBatch Countとして表示される。この値や前述のSetPass Callの値が最適化を行う時の指針として判断していくことになる。この値はゲームを実行した時にStatsタブを選択した時に確認することが出来る。