【Unity】カスタムポストプロセスで平均値フィルタを作る

投稿者: | 2023-12-28

カスタムポストプロセスで平均値フィルタを作ってみました。

シェーダーを作成

Projectウィンドウで右クリックから「HDRP Post Process」を作成します。

シェーダーでは、入力ピクセルの周囲のピクセルの平均値を出力します。まずオフセットの配列を作ります。配列のサイズを動的に設定するとエラーになるのでリテラルにしています。

    float4 CustomPostProcess(Varyings input) : SV_Target
    {
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

        int2 offsets[25]; 
        int index = 0;
        for (int i = -2; i <= 2; i++) 
        {
            for (int j = -2; j <= 2; j++)
            {
                offsets[index++] = int2(i, j);
            }
        }

すべての色を足します。オフセットはピクセル単位なので、ターゲットテクスチャのサイズで割って正規化しています。

        float3 avgColor = float3(0, 0, 0);
    
        for (int i = 0; i < 25; i++)
        {
            float2 offset = offsets[i];       
            float2 texelSize = float2(1 / _ScreenParams.x, 1 / _ScreenParams.y);
            float2 coord = ClampAndScaleUVForBilinearPostProcessTexture(input.texcoord.xy + offset * texelSize.xy);
            float3 color = SAMPLE_TEXTURE2D_X(_MainTex, s_linear_clamp_sampler, coord).xyz;
            avgColor += color;
        }

一辺が5なので、5 * 5 = 25回繰り返します。結果を25で割って平均値を計算します。

        avgColor /= 25;

Float型のプロパティでエフェクトの強度を調節しています。0のとき元の色を、1では平均の色を出力します。

        float3 sourceColor = SAMPLE_TEXTURE2D_X(_MainTex, s_linear_clamp_sampler, ClampAndScaleUVForBilinearPostProcessTexture(input.texcoord.xy)).xyz;

        float3 finalColor = lerp(sourceColor, avgColor, _Intensity);

        return float4(finalColor, 1);
    }

ポストプロセスボリュームを作成

「HDRP C# Post Process Volume」を作ります。

定数の値を作成したシェーダー名に置き換えます。

    const string kShaderName = "Hidden/Shader/AverageFilterTest";

プロジェクト設定のHDRP Global Settingsでカスタムポストプロセスを追加します。

Volumeコンポーネントで「Add Override」からカスタムポストプロセスを追加して、プロパティをオーバーライドします。

スライダーでフィルターのかかり具合を調節できます。

0
1

コメントを残す

メールアドレスが公開されることはありません。