I decided in my 2d game to add depth so that you could set on which plan objects should be drawn and ran into such a problem: how to choose the correct glBlendFunc . For texturing, I use png , so I initially used a function of this type:

 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

As far as I can tell, this function uses alpha for blending, which I can only have 2 values: 0 (for transparency ) and 1 (if there is anything). When we mix the background color, for example 0,1,0,1 and transparency , we get the background color (green) with alpha = 1 - and that’s the problem. Since then we can draw an object in the background, and it will already be visible, since the transparency with its alpha = 0 has been replaced with green color, with alpha = 1. I see the way out when mixing, for the final color I chose a smaller alpha , but I can't figure out how to write this in glBlendFunc .

  • one
    Personally, according to your explanation, nothing is clear. Can you give an example, but rather a few? A pair of colors (RGBA): with which you draw, and on top of which you draw. And the result you want to get after mixing. - HolyBlackCat

1 answer 1

Everything is done a little differently. The main secret is to first sort the objects by distance from the camera, and then draw all the opaque at first, and then translucent:

  1. All objects with binary (0/1) or missing transparency are drawn from the near to the far with the use of the Z buffer and clipping of the transparent parts (so that these parts in Z do not write anything). glBlendFunc here any. Enable discard in the shader ( if(color.a <= 0.5) discard; ).

  2. All objects with translucent parts are drawn from the far to the near, with the Z test (so that the more near-opaque ones cover them) and, just, with glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); .

  • If the objects are sorted, then why not draw them all together at once, with z-buffer turned off, from the far to the near? - HolyBlackCat
  • @HolyBlackCat is done to reduce the load on the GPU. Opaque objects do not care in what order they are drawn, but if we draw from front to back, we fill each pixel a maximum of once, for the nearest object (and all other times Z-test will work). If we go the other way round, back to back (without the Z-test), then the pixel can be redrawn several times, in vain. - Kromster
  • Regarding the first part: even before your answer, I found a solution, the same one - do not draw values ​​with alfa 0, but in a different way, not directly from the shader. In gl, there is glAlphaFunc, with which I set the appropriate value and it all worked. - Andrej Levkovitch
  • Although now I look: they are not supported by es - I will try your method - Andrej Levkovitch