2
\$\begingroup\$

I'm trying to get the blend of two images to work without luck.

I have a render target on which I have an object, then I want to render again the same object in same position but with different light condition. My goal is to add the result of this two render so I tried to do something like:

glEnable(GL_BLEND);
glBlendFunc (GL_ONE , GL_ONE);

....
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
render on render target A
change light condition
do not clear now
render on render target A again with new light condition
glDisable(GL_BLEND);
display render target A

I am surely missing something because not only just the first image shows, but the object is transparent.

I am extremely sorry if the question is stupid but I'm very new to such things. Thank you.

edit Following the answer of @Sam Johnston I've edited my code but, although I solved the transparency, the results are not added (to make sure of this I render one with a completely red light and one with a green light) together, but I get just the first render as result:

glEnable(GL_BLEND);
glBlendFunc (GL_ONE , GL_ZERO);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
render on render target A
change light condition
glBlendFunc (GL_ONE , GL_ONE);
do not clear now
render on render target A again with new light condition
glDisable(GL_BLEND);
display render target A

Have I misunderstood the answer?

Juan

\$\endgroup\$
2
\$\begingroup\$

On your first pass, you're additively blending your object into the stuff that's already in the render target. Since your object is presumably opaque, you want to make sure the stuff that's in the render target beneath your object is occluded. You could do this by setting your blend mode to glBlendFunc(GL_ONE, GL_ZERO) and rendering the object completely black, then proceeding with what you've already written. This will cost an extra rendering pass, and is non ideal.

A better solution, I think, is to render the first lighting pass with glBlendFunc(GL_ONE, GL_ZERO) and then all subsequent lighting passes with glBlendFunc(GL_ONE, GL_ONE). That way the first lighting pass will stomp anything already in the render target (effectively occluding what's behind the object) and the remaining lighting passes will add their light contribution onto the object the way you expect.

EDIT: Regarding the OPs update about only seeing the first rendering pass: make sure you set the depth compare function to something that will allow multiple fragments at the same depth to pass. You must use GL_LEQUAL or GL_EQUAL for each pass after the first (assuming your depth buffer is such that 1.0f represents the far plane and 0.0f represents the near plane).

\$\endgroup\$
  • \$\begingroup\$ thank you very much for the answer but I still have problems, I edited the code in the question \$\endgroup\$ – juan_morata Jul 28 '14 at 17:16
  • 1
    \$\begingroup\$ Regarding what you said in your edit: what's your depth mode? If you're rendering the same object multiple times, you'll need to make sure you're using GL_LEQUAL or GL_EQUAL for your depth compare function. If you're using GL_LESS none of your fragments will pass the depth test! \$\endgroup\$ – Sam Johnston Jul 28 '14 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.