Sign in to follow this  
smallGame

Blending troubles

Recommended Posts

Actually I replied too fast, if I remove the Z buffer is nice effect, but I get troubles if there are clouds bhind a hill.

Isn't an other method than sorting them? I want the Z buffer between hills and clouds but not between clouds themself.

Thanks,

Share this post


Link to post
Share on other sites
Disable Z writes AND have Z tests enabled AND either
1) have your billboard alphablend set to src=srcalpha (or one), dst=one. No need to sort. (this is called additive alpha)
2) have your billboard alphablend set to src=srcalpha, dst=invsrcalpha. Render billboarded objects sorted back-to-front. (this is the "true" usual alpha blend)

Note that with 1) and 2) the visual outcome is different. Try whichever suits you better.

Also, always render your solid nontransparent objects first (with Z writes and Z tests on), followed by the rendering of transparent objects. When rendering transparent objects, you usually only only have Z writes on if you're using alpha testing at the same time.

There's just no way around it: Z-buffering doesn't work too well with transparent objects. You can google for "order-independent transparency" or "sort-independent transparency" for some research papers on the topic.

Share this post


Link to post
Share on other sites
Sorry I didn't get it, I tried the following code :


1)
[souce code="cpp"]
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_WRITEMASK);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFunc(GL_DST_ALPHA, GL_ONE);
[/source]

2)
[souce code="cpp"]
glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_WRITEMASK);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
[/source]

I render solid nontransparent objects first.

Share this post


Link to post
Share on other sites
It's been a while since I've done OpenGL, but let's see..

1) I don't see GL_DEPTH_WRITEMASK being a valid value for glEnable. Also, setting glBlendFunc twice like that just overrides the first mode. I'd try

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);



2)

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);



When using 1) for transparent blending, you don't need to sort back-to-front, but when using the BlendFunc in 2), you do need to sort.

Share this post


Link to post
Share on other sites
Thanks for your help but I am still in trouble, I am interested by the 1) blending. I don't manage the
 glDepthMask(GL_FALSE); 
function. I read I don't have to put it between glBegin(...) and glEnd(). But I am not because I don't use such functions.

That's what I get:



link

I suppose is the way I manage glDepthMask.

I copy my drawing method that is really simple:

[source code="cpp"]
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);

if (particle) {
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);

} else {
glDepthMask(GL_TRUE);

}

glPushMatrix();
glMatrixMode(GL_PROJECTION);
glEnable(GL_TEXTURE_2D);
glLoadMatrixf(proj->mV);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(modView->mV);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

float* vert = (float*)vertices;
glVertexPointer(3, GL_FLOAT, 32, vert);
vert += 3;
glTexCoordPointer(2, GL_FLOAT, 32, vert);
vert += 2;
glNormalPointer(GL_FLOAT, 32, vert);

glDrawElements(GL_TRIANGLES, getSizeIndices(), GL_UNSIGNED_INT, indices);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);

glPopMatrix();

if (particle){
glDisable(GL_BLEND);
}



Thanks for your help.

Share this post


Link to post
Share on other sites
Can you double-check that your render order is like

Begin frame, clear Zbuffer and color buffer.
Render green terrain, Zwrite and Ztest on, blending off.
Render particles, Zwrite off and Ztest on, blending additive.
Present frame.


Also, remember to restore the state completely, I think at the last few lines where you have

if (particle){
glDisable(GL_BLEND);
}


shouldn't you have instead

if (particle){
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}


I think now the particles show behind the terrain because
a) They really are behind the terrain (which apparently isn't true here, but double-check that)
b) You render your terrain *after* you render your particles, which is wrong, since it is not possible to use Zwrites with alpha-blended objects.

Share this post


Link to post
Share on other sites
Quote:
Original post by clb
Also, remember to restore the state completely, I think at the last few lines where you have

if (particle){
glDisable(GL_BLEND);
}


shouldn't you have instead

if (particle){
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}



You 're right, it's working now, thanks a lot for your patience and your explanations.

Quote:
Original post by clb
I think now the particles show behind the terrain because
a) They really are behind the terrain (which apparently isn't true here, but double-check that)

That's is the effect expected


Quote:
Original post by clb
b) You render your terrain *after* you render your particles, which is wrong, since it is not possible to use Zwrites with alpha-blended objects.

No I am not.



link


Thanks a lot,

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this