I have the following function inside fragment shader, but it reduces fps by 7
half3 ClusterAndDithering(half3 color, half2 uv)
{
half2 clusters = half2(16, 16);
color.xyz = RgbToHsv(color.xyz);
color.yz = round(color.yz * clusters);
half2 centerUV = half2(0, 0);
centerUV.x = floor(uv.x * _BaseMap_TexelSize.z) / _BaseMap_TexelSize.z;
centerUV.y = ceil(uv.y * _BaseMap_TexelSize.w) / _BaseMap_TexelSize.w;
half2 UVDither = fmod(centerUV, _BaseMap_TexelSize.xy * 2) * _BaseMap_TexelSize.zw;
half Min = min(UVDither.x, UVDither.y);
half Odd = 1 - fmod(color.z, 2);
half Val = color.z > clusters / 2 ? 0 : 1;
half Dither = Min * Odd * Val;
color.z = (color.z + Dither);
color.yz /= clusters;
color = HsvToRgb(color);
return color;
}
This code reduces SV chanel variant and making dithering (making grid from center of UV).
For example here's Min value result:
Odd:
Val:
No clustering or dithering:
Dithering and clustering:
Any ideas how to optimize it?
Upd:
Changed code a bit (it didn't help, but looks better).
half3 ClusterAndDithering(half3 color, half2 uv)
{
half2 clusters = half2(8,8);
color.xyz = RgbToHsv(color.xyz);
color.yz = round(color.yz * clusters);
half2 centerUV = half2(0, 0);
centerUV.x = floor(uv.x * _BaseMap_TexelSize.z);
centerUV.y = ceil(uv.y * _BaseMap_TexelSize.w);
centerUV = fmod(centerUV, 2);
half Min = min(centerUV.x, centerUV.y);
half Odd = 1 - fmod(color.z, 2);
half Val = color.z > clusters.y / 2 ? 0 : 1;
half Dither = Min * Odd * Val;
color.z = (color.z + Dither);
color.yz /= clusters;
color = HsvToRgb(color);
return color;
}
Usage inside fragment function:
half4 LitPassFragment(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
SurfaceData surfaceData;
InitializeStandardLitSurfaceData(input.uv, surfaceData);
InputData inputData;
InitializeInputData(input, surfaceData.normalTS, inputData);
half4 color = UniversalFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
color.rgb = ClusterAndDithering(color.rgb, input.uv);
color.rgb = MixFog(color.rgb, inputData.fogCoord);
return color;
}
question from:
https://stackoverflow.com/questions/65839763/how-to-optimize-color-reduction-and-dithering 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…