Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

unity3d - How to optimize color reduction and dithering

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: enter image description here Odd: enter image description here Val: enter image description here No clustering or dithering: enter image description here Dithering and clustering: enter image description here 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Finally found custom function to convert RGB to HSV and vice versa. It's faster than Unity's built-in. There's no another ways to optimize that code, at least you know how to multiply round and divide value with one function.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...