OpenGL Problem with blend func

Accname

2D-Graphics enthusiast
Reaction score
1,462
Hi,
I currently have a problem with the blend function in my lwjgl openGL program.

The current blend function i am using is:
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
As i have read that it is the standard blend function used for RGBA images.

But the problem is, the alpha channel is not used properly.
If i am drawing an image on top of another image, and the image with the higher Z-level has pixels with an alpha below 255 then it will always be blended with black.
Look at this example image:
PlanetPreview.png

The "Stars" have a higher Z-value then the "Planet". Its a 32bit RGBA png image and alpha is set correctly for the image if i view it with Pain.net / other programs.
But when drawing its always blended on top of black colour.

Can anybody please point out what kind of setting I ve got wrong?
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
I think it has to do with the depth test i am using:
Code:
GL11.glEnable(GL11.GL_DEPTH_TEST);
            GL11.glDepthFunc(GL11.GL_LEQUAL);
The documentation of opengl says the following about the depth function:
glDepthFunc specifies the function used to compare each incoming pixel depth value
with the depth value present in the depth buffer.
The comparison is performed only if depth testing is enabled.
Might that be the reason for the problem?
But how would i implement alpha blending in combination with the depth func then?
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
I ve read somewhere that i need to deactivate the depth buffer when i want transparency blended with my scene. Is this correct? Isnt their an easier way if i want transparent objects to still be sorted by depth?
 

s3rius

Linux is only free if your time is worthless.
Reaction score
130
Uhmm let's see.. I'm know very knowledgeable with blending but the problem is how the depth buffer works.
It doesn't care WHAT kind of pixel you've written into it, it just cares that you did. So imagine you have some transparent surface and behind that a non-transparent one.
Now your program first draws the transparent surface by mixing the color of the surface (let's say red) with the background (let's say black) and draws your surface as a very blackish red. It *looks* transparent but it actually isn't, it's just a different color.

Now you draw the opaque surface behind the transparent one. OpenGL checks the depth buffer and sees that there's already a surface in front of that one, so no need to draw something that is obstructed anyway. It doesn't know that the pixels are supposed to be transparent.

That's what you see in your picture, I think. The black blobs around your stars is actually the background. It's not been drawn over by the earth because you've given it a higher z-value by printing a star over it.

What to do? Transparency is tricky. There are no good and easy ways to use both opaque and transparent objects without problems.
What is usually done is:
1) First draw all non-transparent objects onto the screen.
2) Sort all the transparent objects from far to near z order
3) Draw the transparent objects, begining with the ones farthest away from the camera.

This way you won't have your background bleed through.
You start with the objects furthest away because depth ordering between two transparent objects suffer from the same problem described above.

Technically you could simply sort ALL objects from back to front and simply draw them all this way, but usually you want non-transparent objects to be draw front-to-back instead. This way OpenGL can rule out which objects are obstructed and not draw them at all.

Of course this is all asuming that it's the actual problem. As I said I'm not too proficient with transparency.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Uhmm let's see.. I'm know very knowledgeable with blending but the problem is how the depth buffer works.
It doesn't care WHAT kind of pixel you've written into it, it just cares that you did. So imagine you have some transparent surface and behind that a non-transparent one.
Now your program first draws the transparent surface by mixing the color of the surface (let's say red) with the background (let's say black) and draws your surface as a very blackish red. It *looks* transparent but it actually isn't, it's just a different color.

Now you draw the opaque surface behind the transparent one. OpenGL checks the depth buffer and sees that there's already a surface in front of that one, so no need to draw something that is obstructed anyway. It doesn't know that the pixels are supposed to be transparent.

That's what you see in your picture, I think. The black blobs around your stars is actually the background. It's not been drawn over by the earth because you've given it a higher z-value by printing a star over it.

What to do? Transparency is tricky. There are no good and easy ways to use both opaque and transparent objects without problems.
What is usually done is:
1) First draw all non-transparent objects onto the screen.
2) Sort all the transparent objects from far to near z order
3) Draw the transparent objects, begining with the ones farthest away from the camera.

This way you won't have your background bleed through.
You start with the objects furthest away because depth ordering between two transparent objects suffer from the same problem described above.

Technically you could simply sort ALL objects from back to front and simply draw them all this way, but usually you want non-transparent objects to be draw front-to-back instead. This way OpenGL can rule out which objects are obstructed and not draw them at all.

Of course this is all asuming that it's the actual problem. As I said I'm not too proficient with transparency.
Yeah, i have already got that, more or less.
I was reading through some articles i found by googling all kinds of combinations of "opengl" "depth function" and "blend function".
And i understand the problem.
But i am a little bit disappointed by this behaviour.
I mean, it would not be that hard for the depth buffer to take a pixels alpha into account and use the blending function.
I was just hoping there would be a simple solution to this. If i just knew earlier i had to sort them myself @_@.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top