mcpField
M
mobile-post-processing

mobile-post-processing

github.com/adevra開発1646 回インストール31 週間前に更新
リポジトリ

mobile-post-processing について

モバイルおよび WebGL 向け Unity URP のポストプロセスを追加・最適化するスキルです。画面空間エフェクトの負荷比較とシングルパス実装の指針を提供します。

主な機能

  1. 01エフェクトを統合して全画面 Blit を削減
  2. 02シングルパスのポストプロセス例を提示
  3. 03一般的なエフェクトのモバイル負荷を比較
  4. 04URP Renderer Features の利用を推奨

活用シーン

  1. 01モバイルゲームのポストプロセス負荷を削減
  2. 02URP にカスタムパスを追加
  3. 03制約のあるハードウェア向けの画面エフェクト選定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/adevra/unity-shader-agent-skills --skill mobile-post-processing

インストール後、Claude Code で/mobile-post-processingを入力して読み込まれたか確認します。

詳細

Unity URP 向けモバイル後処理

トリガー

ユーザーがモバイルまたは WebGL 向けに Unity の後処理エフェクトを追加、作成、最適化したい場合に、このスキルを使用します。トリガーには、「post-processing」、「bloom」、「vignette」、「color grading」、「blur」、「outline」、「edge detection」、「chromatic aberration」、「Renderer Feature」、「Full Screen Pass」、「Blit」、「post-process mobile」、または制約のあるハードウェアでのスクリーンスペースエフェクトに関する言及が含まれます。また、ユーザーがモバイルで後処理によるフレーム落ちを報告した場合もトリガーします。


基本ルール

  1. 後処理の各パスでは、フルスクリーンの Blit が発生します — フレームバッファー全体をメインメモリから読み込み、書き戻します。タイルベースのモバイル GPU では、タイルメモリがフラッシュされます。ミドルレンジのモバイル端末では、パスごとに 0.5~2ms を見込んでください。

  2. 可能な限り、すべてのエフェクトを単一のパスにまとめてください。 Unity のデフォルトの後処理スタックでは、各エフェクトが個別のパスとして実行されます。モバイルでは、これだけで 6ms 以上かかることがあります(実測値:端末によってはビネットだけで 6ms)。代わりに、シングルパス方式を使用してください。

  3. Bloom が特に必要な場合を除き、HDR を無効にしてください。 HDR はフレームバッファーの帯域幅を 2 倍にします(チャンネルあたり 16 ビット浮動小数点から 8 ビットへ)。カラーグレーディングだけが必要な場合は、LDR で適用してください。

  4. Bloom は、モバイルで使用するデフォルトエフェクトの中で最もコストが高いものです。 ダウンサンプリング、ぼかし、アップサンプリングが必要になるため、複数のパスが発生します。必要な場合は、反復回数を減らし(最大 2~3 回)、半解像度のぼかしを使用し、高品質のプリフィルターを省略してください。

  5. モバイルでは、モーションブラーや被写界深度を使用しないでください。 複数のパスにわたって、フラグメントごとに複数のテクスチャサンプルが必要になります。

  6. URP でカスタムエフェクトを使用する場合は、Volume ベースの後処理よりも Renderer Feature を優先してください。 Renderer Feature なら、Blit を実行するタイミングと方法を直接制御できます。


シングルパス後処理のテンプレート

この方法では、ビネット、カラーグレーディング、シンプルな Bloom を 1 つのパスにまとめます。

Shader "Mobile/PostProcess_SinglePass"
{
    Properties
    {
        _MainTex ("Source", 2D) = "white" {}
        _VignetteIntensity ("Vignette Intensity", Range(0, 1)) = 0.3
        _VignetteRadius ("Vignette Radius", Range(0, 1)) = 0.7
        _Contrast ("Contrast", Range(0.5, 1.5)) = 1.1
        _Saturation ("Saturation", Range(0, 2)) = 1.1
        _Brightness ("Brightness", Range(0.5, 1.5)) = 1.0
    }
    
    SubShader
    {
        Tags { "RenderPipeline" = "UniversalPipeline" }
        
        Pass
        {
            ZTest Always ZWrite Off Cull Off
            
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            
            CBUFFER_START(UnityPerMaterial)
                half _VignetteIntensity;
                half _VignetteRadius;
                half _Contrast;
                half _Saturation;
                half _Brightness;
            CBUFFER_END
            
            TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
            
            struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; };
            struct Varyings  { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; };
            
            Varyings vert(Attributes v)
            {
                Varyings o;
                o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
                o.uv = v.uv;
                return o;
            }
            
            half4 frag(Varyings i) : SV_Target
            {
                half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
                
                // --- Vignette (no extra texture sample) ---
                half2 uvCentered = i.uv - 0.5h;
                half vignette = 1.0h - saturate(
                    length(uvCentered) / _VignetteRadius
                );
                vignette = smoothstep(0.0h, 1.0h, vignette);
                color.rgb *= lerp(1.0h, vignette, _VignetteIntensity);
                
                // --- Brightness / Contrast ---
                color.rgb *= _Brightness;
                color.rgb = (color.rgb - 0.5h) * _Contrast + 0.5h;
                
                // --- Saturation ---
                half luminance = dot(color.rgb, half3(0.2126h, 0.7152h, 0.0722h));
                color.rgb = lerp(luminance.xxx, color.rgb, _Saturation);
                
                return saturate(color);
            }
            ENDHLSL
        }
    }
}

URP Renderer Feature(C# の設定)

後処理パスを URP に挿入するには:

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

public class MobilePostProcessFeature : ScriptableRendererFeature
{
    [System.Serializable]
    public class Settings
    {
        public Material material;
        public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
    }
    
    public Settings settings = new Settings();
    MobilePostProcessPass pass;
    
    public override void Create()
    {
        pass = new MobilePostProcessPass(settings);
    }
    
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        if (settings.material == null) return;
        renderer.EnqueuePass(pass);
    }
    
    class MobilePostProcessPass : ScriptableRenderPass
    {
        Settings settings;
        RTHandle tempRT;
        
        public MobilePostProcessPass(Settings settings)
        {
            this.settings = settings;
            this.renderPassEvent = settings.renderPassEvent;
        }
        
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            var cmd = CommandBufferPool.Get("MobilePostProcess");
            var source = renderingData.cameraData.renderer.cameraColorTargetHandle;
            
            // Single blit with our combined shader
            Blitter.BlitCameraTexture(cmd, source, source, settings.material, 0);
            
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    }
}

モバイル向け安全なエフェクト(コスト順)

エフェクトコストモバイルでの評価備考
カラーグレーディング(LDR)約 0.1ms安全純粋な演算で、追加のサンプルなし
ビネット約 0.1ms安全UV 距離の計算のみ
フィルムグレイン約 0.2ms安全UV 計算によるノイズで、テクスチャ不要
シンプルなアウトライン(深度)約 0.5ms注意深度テクスチャと近傍 4 点のサンプルが必要
Bloom(2 回反復)約 1~2ms注意半解像度を使用し、反復は最大 2 回
色収差約 0.3ms注意テクスチャサンプルが 1 回ではなく 3 回
ぼかし(シングルパスのボックス)約 0.5ms注意4 タップのボックスブラーを使用し、ガウシアンは使用しない
モーションブラー約 3~5ms回避速度に沿った複数のサンプルが必要
被写界深度約 3~5ms回避CoC の計算と可変ブラーが必要
スクリーンスペース反射約 4~8ms回避スクリーンスペースでのレイマーチングが必要
アンビエントオクルージョン(SSAO)約 2~4ms回避フラグメントごとに複数の深度サンプルが必要

参考リポジトリ

リポジトリ目的重要な理由
demonixis/FastPostProcessingシングルパスのモバイル向けポストエフェクトモバイル向けの第一候補です。 すべてが 1 つのパスにまとまっています。
TPiotr/SimpleMobilePostProcessing-UnityぼかしとビネットUnity のビネットだけで 6ms かかったことをきっかけに作成されました
yahiaetman/URPCustomPostProcessingStackURP Volume 対応のカスタムポストエフェクトURP に適切に統合された 8 つのエフェクト例
QianMo/X-PostProcessing-Library多数のエフェクト(MIT)デスクトップ品質の参考資料です。モバイル向けに調整してください
GarrettGunnell/Post-Processingモジュール式の Bloom、カラーグレーディング、エッジシングルパスへの集約に関する解説

参考資料

コメント