# Blending troubles

## Recommended Posts

link link How you can see on the screenshots in green the blending is correct and in red there is a big problem. I don't understand why there is a such problem. And what not every time. If someone has any idea, thanks to help me.

##### Share on other sites
Disable z-write (or z-test) or sort your quads back to front.

##### Share on other sites
Thanks, that's was quick and efficient.

##### Share on other sites
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 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 on other sites
Sorry I didn't get it, I tried the following code :

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

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

I render solid nontransparent objects first.

##### 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 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:

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 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 on other sites
Quote:
 Original post by clbAlso, remember to restore the state completely, I think at the last few lines where you haveif (particle){ glDisable(GL_BLEND);}shouldn't you have insteadif (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 clbI think now the particles show behind the terrain becausea) 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 clbb) 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.

Thanks a lot,

## 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

• ### Forum Statistics

• Total Topics
628362
• Total Posts
2982266

• 10
• 9
• 13
• 24
• 11