OpenGL and selective texture blending

Started by
7 comments, last by strivingJuno 13 years, 9 months ago
Hello world.

How can I avoid partially transparant textures being blended with the background of my scene? Consider a set of textures that compose a 2D-map. I want to (gradually) blend only the transitions from one texture to another and not the transitions from texture to background. Textures should be transparent only for textures, and opaque for the background...

Thanks for any reply.
Advertisement
If you mean that you just want to transition from one texture to another, then draw the first texture with full opacity, and then render the other texture above it, although this only works if textures would be fully opaque without the transition.

I'm going by the assumption you aren't using multitexturing.
Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.
No, I don't use multi-texturing.

Quote:Original post by ashwathh
...although this only works if textures would be fully opaque without the transition


Exactly this is what I want to solve...

To depict my problem, have a look at the following sketch:
http://yfrog.com/edblendingsketchp
Use the stencil buffer and render each surface two times. Here's some pseudo code to demonstrate the idea.

clearStencilBuffer();set zbuffer check to: lesser thanfor each surface do{  // init stencil check  set stencil: render only if stencilvalue = 0    // render surface, first pass  render surface without blending and write stencilvalue = 1  // update stencil check  set stencil: render only if stencilvalue = 1  // render surface, second pass  render surface with blending}
Ashaman, thank you for your reply. I already played with stencil buffers, but had no success. I've implemented your suggestion, but failed again. The main issue was: if I enable depth test, there is nothing rendered. However, if I disable depth testing, the textures are shown correctly - but still: the transitions from texture to background are blended - this is not what I want...

Can you please have a look at my code? Hopefully you find just a bug...

// Prepare texture painting.glEnable(GL_TEXTURE_2D);// glEnable(GL_DEPTH_TEST);// glDepthFunc(GL_LESS);glColor4f(1.0f, 1.0f, 1.0f, 1.0f);// Loop over images and draw.for(int i=0; i<nImages; ++i){   drawTexture(i);}// glDisable(GL_DEPTH_TEST);glDisable(GL_TEXTURE_2D);


In drawTexture(i), the following GL instructions are called.

// For each image, I do:// Set-up stencil buffer pass. Don't update color or depth.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);glEnable(GL_STENCIL_TEST);glStencilFunc(GL_ALWAYS, 0x1, 0x1);glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);// Draw texture.drawTexture(image, pose);// Switch off writing of stencil buffer.// Switch on writing color (and depth).glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);// Draw the area where more than one texture is available.glStencilFunc(GL_EQUAL, 0x1, 0x1);glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);// In that region, alpha blending is enabled.glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// Draw texture.drawTexture(image, pose);// Disable blending.glDisable(GL_BLEND);glDisable(GL_STENCIL_TEST);
Quote:Original post by strivingJuno
Ashaman, thank you for your reply. I already played with stencil buffers, but had no success. I've implemented your suggestion, but failed again. The main issue was: if I enable depth test, there is nothing rendered. However, if I disable depth testing, the textures are shown correctly - but still: the transitions from texture to background are blended - this is not what I want...

Ok, reset :-) I need more information. Take photoshop or gimp and try to archive your effect with different layers ! Are you rendering a 3d scene or 2d scene ? Are the textures applied to one surface or are there different surfaces ? Is there an example of your effect in any other game ?



The context I'm working with is stitching. (You might know AutoStich). So the scene I try to draw is 2D. One of the easiest techniques to avoid seams between the images, is to blend from one image to the other.


I drew a few simplistic sketches in GIMP to depict my situation. Of course, when stitching images, we have images with common content in the overlapping area. I just used two colored squares to better visualize my OpenGL-problem. (Hope it's clear enough)

Starting point.
What I have, but what I don't want. Note that I draw the gradually transparent borders with the help of GLSL shaders.
What I want.

So the goal is to blend from one image to another, but not to blend from one image to the background...

[Edited by - strivingJuno on July 8, 2010 6:54:15 AM]
Ok, then I would sugguest to turn the ztest off and just work with the stencil buffer. Hers's a modified and untested version of your code:

// For each image, I do:// Set-up stencil buffer pass. Don't update color or depth.// WRONG: you need to write the color//glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);glEnable(GL_STENCIL_TEST);// NOTE: render opaque part to background(stencil bit 1 = false) only !glStencilFunc(GL_EQUAL, 0x0, 0x1);glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);// Draw texture.drawTexture(image, pose);// Switch off writing of stencil buffer.// Switch on writing color (and depth).// NOTE: no need to set the color mask//glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);// NOTE: blend ontop of already drawn surfaces only (stencil bit 1 = true)//       if opaque has already been drawn in the first pass, you will  //       alpha blend the surface with itself which will not matterglStencilFunc(GL_EQUAL, 0x1, 0x1);glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);// In that region, alpha blending is enabled.glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// Draw texture.drawTexture(image, pose);// Disable blending.glDisable(GL_BLEND);glDisable(GL_STENCIL_TEST);


Good luck :)
Awesome!!! That helped. Just had to comment out the glColorMask commands (I took these from a stencil-buffer tutorial...) Thanks a lot :)

This topic is closed to new replies.

Advertisement