1-bit dithering shader

Screen space shader
Dithering texture map
Shader "Unlit/Dithering"
{
    Properties
    {
        _Color ( "Color Tint ", Color) = (1,1,1,1)
        _TileFactor ("tile size", float) = 1.0
        _DitherCount ("dither level", float) = 19
        _DitherTex ("Dither Ramp", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Tags { "LightMode" = "ForwardBase" }
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"
            
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 screenPosition : TEXCOORD0;
                float3 normal : TEXCOORD1;
                float4 worldPos : TEXCOORD2;
                float3 lightColor : TEXCOORD3;
                SHADOW_COORDS(4)
            };
            fixed4 _Color;
            float _TileFactor;
            float _DitherCount;
            sampler2D _DitherTex;
            float4 _DitherTex_ST;

            float remap(float v, float s, float e, float s2, float e2)
            {
                return (v-s)/(e-s) * (e2-s2) + s2;
            }
            float2 repeat(float2 uv, float offset, float interval)
            {
                float fraction = uv.x % interval;
                uv.x = fraction + offset;
                uv.y = frac(uv.y);
                return uv;
            }
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.normal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.screenPosition = ComputeScreenPos(o.pos);
                
                // 4 vertex light
                float3 col = Shade4PointLights(unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
                    unity_LightColor[0], unity_LightColor[1],unity_LightColor[2], unity_LightColor[3],
                    unity_4LightAtten0 ,
                    o.worldPos,o.normal);
                
                o.lightColor = col;
                
                TRANSFER_SHADOW(o);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // pixel directional light
                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                fixed intensity = dot(lightDir, i.normal) * 0.5 + 0.5;
                float ditherFactor = (intensity  * _LightColor0 + i.lightColor.r)* _DitherCount;
                
                float2 textureCoordinate = i.screenPosition.xy / i.screenPosition.w;
                float aspect = _ScreenParams.x / _ScreenParams.y;
                textureCoordinate.x = textureCoordinate.x * aspect;
                textureCoordinate.y *= _DitherCount;
                textureCoordinate *= _TileFactor;
                // remap uv to corresponding texture region
                float2 mappedUV = repeat(textureCoordinate, floor(ditherFactor)/_DitherCount, 1.0/_DitherCount);
                // sample and choose texture
                fixed4 col = tex2D(_DitherTex, mappedUV);
                
                UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
                float shadow =SHADOW_ATTENUATION(i);
                fixed4 finalColor = fixed4(col.rgb * _Color.rgb * atten * shadow, 1.0);
                return finalColor;
            }
            ENDCG
        }
        
    }
    //FallBack "Diffuse"
}
Dithering effect with post processing shader
Shader "Unlit/PPDitering"
{
Properties{
[HideInInspector]_MainTex ("Texture", 2D) = "white" {}
_TileFactor ("tile size", float) = 1.0
_Balance ("brightness shift", Range (0.0,2)) = 1.0
_DitherCount ("dither level", float) = 19
_DitherTex ("Dither Ramp", 2D) = "white" {}
}

SubShader{
Cull Off
ZWrite Off
ZTest Always

Pass{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag

sampler2D _MainTex;
float _TileFactor;
float _DitherCount;
sampler2D _DitherTex;
float _Balance;

float2 repeat(float2 uv, float offset, float interval)
{
float fraction = uv.x % interval;
uv.x = fraction + offset;
uv.y = frac(uv.y);
return uv;
}

struct appdata{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};

struct v2f{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};

v2f vert(appdata v){
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;

return o;
}

fixed4 frag(v2f i) : SV_TARGET{
//get source color from texture
fixed4 col = tex2D(_MainTex, i.uv);
float ill = 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b;
float ditherFactor = ill * _DitherCount * _Balance;
float2 textureCoordinate = i.uv;
float aspect = _ScreenParams.x / _ScreenParams.y;
textureCoordinate.x *= aspect;
textureCoordinate.y *= _DitherCount;
textureCoordinate *= _TileFactor;
// remap uv to corresponding texture region
float2 mappedUV = repeat(textureCoordinate, floor(ditherFactor)/_DitherCount, 1.0/_DitherCount);
fixed4 pattern = tex2D(_DitherTex, mappedUV);
return pattern;
}

ENDCG
}
}
}