ポストプロセッシングは、ブルーム(発光効果)やカラーグレーディングを適用してゲーム画面の空気感を一気に引き上げる素晴らしい機能です。しかし、これをモバイルデバイスやMeta QuestのようなスタンドアロンVR向けの開発でそのまま使用すると、GPUの限界を容易に突破し、致命的な処理落ちを引き起こします。本記事では、モバイルGPUのメモリ構造に起因するこの高負荷バグの仕組みを『写真現像とメイクの二重手間』の例え話を交えて分かりやすく解説し、見た目の美しさを保ちながらFPSを劇的に改善するための最適化設定を提示します。

1. 例え話で理解する:『写真現像とメイクの二重手間』による作業台のパンク

なぜモバイルやVRデバイスにおいて、ポストプロセスがここまで異常に重いのでしょうか。これを『写真現像所での巨大な画用紙の出し入れ作業』に例えて説明します。

料理人やアーティストの作業台(GPUの内部メモリであるタイルキャッシュ)を想像してください。モバイルのグラフィックチップは、この作業台が非常に狭い代わりに、作業台の上だけで素早く絵を描き終える(不透明オブジェクトの描画など)のを得意としています。しかし、ポストプロセスという処理は、撮影した写真(画面全体のピクセルデータ)を取り出して加工する『画像処理メイク』です。

このメイクを行う際、処理システム(ポストプロセスパス)は、『巨大な画用紙(フルスクリーンバッファ)を倉庫(VRAM)から持ってきて机に広げる』『一部分にブラー(ぼかし)を塗るために、もう一枚の巨大なトレーシングペーパー(中間テクスチャ)を倉庫から持ってきて重ねる』『終わったら、一度倉庫に片付けて、次のエフェクト(Bloomなど)のためにまた別の巨大な紙を倉庫から持ってくる』という、倉庫と机の間の巨大な紙の往復搬送(メモリのロード・ストア)を毎フレーム何十回も繰り返します。

モバイルGPUにとって、この「倉庫と作業台を繋ぐ通路の幅(メモリ帯域/Memory Bandwidth)」は非常に狭く制限されています。そのため、巨大な画用紙の往復搬送だけで通路が完全に大渋滞を起こし(帯域幅のパンク)、GPU自体の計算能力が余っているにもかかわらず、紙の到着を待つ無駄な時間(メモリ待機ストール)が発生してフレームレートが奈落の底に落ちてしまうのです。特に画面解像度が高い最新のスマートフォンや、左右の目用に2枚の巨大な絵を描くVR(Meta Quest)環境では、この無駄が2倍、3倍に膨れ上がります。

2. 解決策A:高負荷エフェクトの完全排除とBloomの『Fast』化

最も確実な対策は、モバイルGPUの狭い作業台を破綻させる『巨大な紙の往復』を強いるエフェクトをインスペクター上で完全に無効化し、かつ主要なエフェクトの処理を簡略化することです。

無効化・調整すべき設定項目:

  1. 被写界深度(Depth of Field):完全無効(最優先)
    ピクセル周辺を広範囲にサンプリングしてぼかすこの処理は、モバイルGPUにとっては数万回の追加メモリバインドを要求する致命的な負荷となります。UIプレビューなどでどうしても必要な場合は、背景のRenderTexture側をあらかじめぼかして描画するなどの代替処理を行います。
  2. モーションブラー(Motion Blur) / 色収差(Chromatic Aberration):無効化
    画面の動きに合わせてピクセルをずらしながらサンプリングするこの機能も、メモリの読み込み負荷が非常に高く、実機では高熱の原因になります。
  3. Bloom(発光エフェクト):品質を『Fast』へ
    Bloomは画面の光っている部分を抽出し、解像度を1/2, 1/4, 1/8と縮小コピーしながらぼかして再度加算合成する処理(ピラミッドブラー)を行います。インスペクターでBloomの設定を開き、Qualityを『Fast』に切り替えることで、この縮小コピー(パス)の回数を減らし、メモリ帯域への負担を半分以下に抑えられます。

3. 解決策B:動的なレンダースケール(Render Scale)の適用

画面全体の解像度が上がると、ポストプロセスの対象ピクセル数は掛け算式に増加します。例えば、4Kディスプレイのスマートフォンでは、Full HDの4倍のピクセルを毎フレーム処理しなければなりません。この問題に対しては、C#スクリプトから動的にレンダースケールを僅かに下げるアプローチが非常に有効です。

以下のスクリプトは、モバイル実機での実行時のみ、描画解像度を適切にスケールダウンしてポストプロセスによるメモリ帯域のパンクを回避する制御プログラムです。

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class MobileResolutionOptimizer : MonoBehaviour
{\
    [Range(0.5f, 1.0f)]
    public float mobileRenderScale = 0.85f; // モバイル実機でのレンダースケール

    void Start()
    {
        #if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS)
        ApplyOptimization();
        #endif
    }

    void ApplyOptimization()
    {
        // 現在使用中の URP Asset を取得
        UniversalRenderPipelineAsset urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
        
        if (urpAsset != null)
        {
            // レンダースケールを 0.85 (解像度を約15%削減) に設定
            // これにより、ポストプロセス対象の総ピクセル数が約28%削減され、メモリ負荷が劇的に下がります
            urpAsset.renderScale = mobileRenderScale;
            Debug.Log($"Mobile optimization applied: Render Scale set to {mobileRenderScale}");
        }
    }
}

この解像度の削減は、スマートフォンの画面が非常に高密度(高PPI)であるため、プレイヤーの肉眼ではほとんど画質の劣化として知覚されません。しかし、GPUにとっては処理すべきピクセル数が約3割近く削減されるため、メモリ帯域に大きな余裕が生まれ、カクつきのない滑らかな60FPS/90FPS動作を実現できるようになります。