Unity3D color removal Shader implementation

Generally, in order to achieve some special rendering effects, the number of colors used in the texture will be reduced. Whether it is implemented in post-processing or implemented on a single object, the idea is similar.
In unity, the color value component can be regarded as a continuous value of [0,1], but in fact, only 256 values ​​can be obtained, so the value of [0,1] can be directly mapped to 256 grids without loss, and then According to the needs, the 256 grids are merged to a certain extent. For example, [0,9] used to be 10 colors, but now it is replaced by the color represented by 0. [10,19] is replaced by the color 10, and so on.

The key code, _DiscreteLevel is the number of colors that need to be used. We use rounding down here, so all colors that fall within this range will be replaced by the starting color of the range. You can also use rounding up as needed, or take this range intermediate colors, and even use palettes to specify colors.

brightness = floor(brightness * 256 / (256 / _DiscreteLevel)) * (256 / _DiscreteLevel) / 256;         

The code provides two ways of gray scale and color. For gray scale, the interval is judged according to the brightness of the pixel. For color, this operation is performed on the three color components respectively.

The effect is as follows, the original picture
Please add a picture description

_DiscreteLevel=4 effect

Please add a picture description

grayscale mode
Please add a picture description

full code

Shader "LX/reduceColor"
{
    
    

    Properties
    {
    
    
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {
    
    }
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _DiscreteLevel("DiscreteLevel",range(1,256))=256
        _GrayScale("_GrayScale",range(0,1))=0.5
    }
    SubShader
    {
    
    
        Tags
        {
    
    
            "RenderType"="Opaque"
        }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
    
    
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        int _DiscreteLevel;
        float _GrayScale;

        void surf(Input IN, inout SurfaceOutputStandard o)
        {
    
    
            float4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            //先计算出亮度
            fixed brightness = Luminance(c.rgb);
            //灰度离散化
            brightness = floor(brightness * 256 / (256 / _DiscreteLevel)) * (256 / _DiscreteLevel) / 256;
            fixed3 grayColor = fixed3(brightness, brightness, brightness);

            //彩色离散化
            fixed r = floor(c.r * 256 / (256 / _DiscreteLevel)) * (256 / _DiscreteLevel) / 256;
            fixed g = floor(c.g * 256 / (256 / _DiscreteLevel)) * (256 / _DiscreteLevel) / 256;
            fixed b = floor(c.b * 256 / (256 / _DiscreteLevel)) * (256 / _DiscreteLevel) / 256;
            fixed3 color = fixed3(r, g, b);

            //插值
            o.Albedo = lerp(color, grayColor, _GrayScale);
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

In addition, the code has also been passed to the github warehouse, you can also pay attention to it~
my github

Guess you like

Origin blog.csdn.net/o83290102o5/article/details/120603857