Glium: Combining depth test and alpha blending


#1

I can get depth testing to work with:

let params = glium::DrawParameters { depth: glium::Depth { test: glium::draw_parameters::DepthTest::IfLess, write: true, .. Default::default() }, };

And I can get alpha blending to work with:

let params = glium::DrawParameters { blend: glium::draw_parameters::Blend::alpha_blending(), .. Default::default() };

But when I try to combine both with:

let params = glium::DrawParameters { depth: glium::Depth { test: glium::draw_parameters::DepthTest::IfLess, write: true, .. Default::default() }, blend: glium::draw_parameters::Blend::alpha_blending(), .. Default::default() };

Alpha blending doesn’t work.

Help appreciated.


#2

There shouldn’t be any problem with doing this.

What makes you think that alpha blending doesn’t work?


#3

I wonder how alpha blending should even work without depth sorting.

Imagine you have already drawn an opaque background and a translucent object in the foreground. If you want to place an object in between, the fragment shader only has the foreground object’s depth and the already blended color available. Theres no way to compute the resulting color.

Maybe this is the phenomenon you observerved as “not working”?


#4

Thanks for the replies.

Alpha blending only works properly when rendered back-to-front. But in this case I either have alpha set to 0 or 1, so depth sorting isn’t necessary.

Here’s what it looks like with depth and alpha blending:

Here’s what it looks like with alpha blending only:
[sorry: only one image allowed]

The second image is how it should look.

The circles are created by a simple fragment shader operating on billboards:

in vec2 textureCoords; out vec4 color; void main() { color = (length(textureCoords-vec2(0.5,0.5))>0.5)?vec4(0.0, 0.0, 0.0, 0.0):vec4(1.0, 0.0, 0.0, 1.0); }


#5

Here’s the alpha-blending only image:


#6

Ah yes, I was too focused on the fact that this would be a problem in glium’s code.

If your alpha is always either 0 or 1, the easiest thing to do is to add a small line to your fragment shader:

if (color.a < 0.5) { discard; }

This will simply make the non-opaque pixels disappear and not write to the depth buffer.