Shader breaks on Windows and M1 Mac (all black)

This is the same issue I faced in my most recent post.


You can see the problem in these two gifs:

my intel macbook:

Client’s m1 macbook / my windows pc:

Last time I fixed it by clamping the glFragColor to 0 after someone mentioned that it could be caused by a negative value breaking on AMD / Nvidia hardware. That doesn’t seem to help this time.

I’m desperately trying to understand what causes this, and how to avoid causing a bug that I’m unable to see on my computer :sweat_smile:. Any insight would be greatly appreciated!!


vec2 coord = uv + offset;
vec2 clampedCoord = clamp(coord, filterClamp.xy,;
vec4 color = texture2D(tDiffuse, clampedCoord);


vec2 coord = uv + offset;
vec4 color = texture2D(tDiffuse, coord);

Does seem to fix the issue on an M1 - not sure what that clamping to .zw does though. Does it also work without that clamp for you?

This fixes it on NVidia hardware:

    // Do clamp :
    vec2 coord = uv + offset;
    vec4 color = texture2D(tDiffuse, coord);

    // Trying to clamp
    gl_FragColor = clamp(color, vec4(0.01), color);

Getting rid of the clamping if-statement works fine. I’m not sure what it’s supposed to do, but keeping it in won’t work anyway, since the clampedCoord variable is gone.

The final result is (from what I can see) the same as the first gif in OP’s post.

1 Like

Wow thanks! This fixed it for me on windows! Hopefully M1 as well.

Any idea why that happens?

Not sure to be honest - this shader is from Pixi.js filter library and I was asked to convert it to ThreeJS. This solution doesn’t seem to fix it on windows :thinking:. Hopefully this repro with the fix from @Harold works on M1 as well!

Thanks a lot for helping!! :pray:

Credit goes to @mjurczyk, he was faster with his response. Didn’t realize he suggested the exact same thing until after I posted it :sweat_smile:

I think whatever you’re clamping clampedCoord to won’t work for some reason. Either the M1 detects this as something strange and ignores it, or it may be some floating point difference (which is bad as well).

This works fine as well, and looks exactly the same as on your first gif (and thus on the M1 I presume?):

    vec2 coord = uv + offset;
    vec2 clampedCoord = clamp(coord, 0., 1.);
    vec4 color = texture2D(tDiffuse, clampedCoord);
    if (coord != clampedCoord) {
        color *= max(0.01, 1.0 - length(coord - clampedCoord));