Blending troubles

Started by
8 comments, last by smallGame 15 years, 5 months ago
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.
Advertisement
Disable z-write (or z-test) or sort your quads back to front.
Thanks, that's was quick and efficient.
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,
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.
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.
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.
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.
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.
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,

This topic is closed to new replies.

Advertisement