カスタムポストプロセスで平均値フィルタを作ってみました。
シェーダーを作成
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」からカスタムポストプロセスを追加して、プロパティをオーバーライドします。
スライダーでフィルターのかかり具合を調節できます。