Return or discard?

The problem started yesterday and I’m unable to tell what caused it (just did many, many things in java). What I saw?

The chain is made of flat squares, everyone have a texture with one element. The texture is transparent so we should see only chain:

The ‘black box’ effect seems to be random, on some chains it exists, on others not. Every chain is the same resource with the same material etc.

Now, as I said, I’m unable to track down all the changes and revert them. I did only some basic tests, and went to the shader. The code:

    float shadow = shadow();
    if (shadow == 0.0) return;

It’s simple, if there is a 100% shadow then don’t do anything, dont calculate the pixel etc.
Something told me to to replace ‘return’ with ‘discard’ and it solved the problem.

So, the question is not how? but why?
What is the subtle difference between return and discard?

Discard discads all changes made. This also includes modification of the depth buffer. A simple return might not write to the color buffer, but depth remains

And why, with ‘return’ sometimes it was ok and sometimes not? On the same screen there is a chain with that boxes and another one without it:

Both of them are rendered with the same shader.

Probably the chain in front gets rendered before the wall, while the chain in the back gets rendered after the wall. If you see issues or not depends on the rendering order

Your chains should be in the transparent bucket or you should use the alphaDiscardThreshold.
Note that if you made your own pre/post shadow shaders you have to implement the alphadiscardThreshold in eachone of them

alphaDiscardThreshold is made exactly like in Lighting.frag
So far everything is ok.

Thanks for answers.