issue while trying to use texture as entry for dithering matrix

Hello,

I am trying to add dithering to standard shader to fade objects in my app.

Here is my surf function :

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            const float4x4 thresholdMatrix =
            {
                1,9,3,11,
                13,5,15,7,
                4,12,2,10,
                16,8,14,6
            };

            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

            float2 pixelPos = IN.screenPos.xy / IN.screenPos.w * _ScreenParams.xy;
       
            float2 uv = pixelPos.xy % _Dithering_TexelSize.zw;
           
            //TEXTURE
            //float threshold = tex2D (_Dithering, uv).r;
           
            //HARD-CODED MATRIX
            float threshold = thresholdMatrix[uv.x][uv.y] / 17.;

            //DITHERING
            clip(c.a - threshold);

            // untouched values
            fixed4 metallic = tex2D(_MetallicGlossMap, IN.uv_MetallicGlossMap);
            o.Metallic = metallic.r;
            o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_BumpMap), _BumpScale).rgb;
            o.Smoothness = metallic.a * _GlossMapScale;
            o.Occlusion = tex2D(_OcclusionMap, IN.uv_OcclusionMap).r * _OcclusionStrength;
            o.Emission = tex2D(_EmissionMap, IN.uv_MainTex) * _EmissionColor;

            o.Alpha = 1.;
            o.Albedo = c.rgb;
        }

When i use the hard coded matrix, everything works fine :

But when I comment the hard coded line and uncomment the line where i sample my texture, the result is disappointing :

Whole parts of the model are clipped.

My texture is imported with those settings :

Hope someone have some clue…

Have a nice day !

UVs are in a normalized 0.0 to 1.0 range. You’re calculating the pixel position and using a modulo of the texture’s resolution. If you have a 4x4 texture that means the “uv” value you’re calculating is going from “0.0 to 3.0” over 4 pixels when you want it to be going from “0.0 to 1.0” over 4 pixels. So instead of getting each texel of your texture in each pixel, you’re getting the same texel in each pixel. You want to be dividing the pixel position by the texture resolution, not getting the modulo of it.

TLDR;
float2 uv = pixelPos.xy * _Dithering_TexelSize.xy;

1 Like

It worked, thank you !