[Re-Solved] Overlapping Transparencies

Problems building or running the engine, queries about how to use features etc.
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

[Re-Solved] Overlapping Transparencies

Post by Moohasha »

I have multiple objects that use the same material, which is just a solid color with 10% alpha. When these objects overlap, however, the alphas add up and you eventually get a solid color. Is there a way to avoid this? If I have 50 of these objects overlapping, I still only want 10% alpha through all of them so I can see what's behind. Do I have to use the stencil buffer or something? What's a good solution for this?
Last edited by Moohasha on Tue Feb 17, 2009 10:49 pm, edited 2 times in total.
Black holes are where God divided by 0
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Re: Overlapping Transparencies

Post by xavier »

What scene blending factor are you using?
Do you need help? What have you tried?

Image

Angels can fly because they take themselves lightly.
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: Overlapping Transparencies

Post by Moohasha »

alpha_blend

Here's my entire material script:

Code: Select all

material Dome
{
    technique
    {
        pass
        {
            lighting off
            ambient vertexcolour
            scene_blend alpha_blend
        }
    }
}
Black holes are where God divided by 0
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: Overlapping Transparencies

Post by Kencho »

Render them to a different target (a render texture), then use that texture on a rectangle that will be overlaid on the scene (opacity of the rectangle: 10%). It's the best I can think right now.
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: Overlapping Transparencies

Post by Moohasha »

So render them to the texture without any transparency, just a solid colo(u)r? Hmm...I've never tried rendering something to a texture instead of the screen, but I'll look into it. Thanks.
Black holes are where God divided by 0
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: Overlapping Transparencies

Post by Kencho »

It's the only way I can think of achieving a non-cumulative blending amongst different entities (and even further, amongst the faces of a non-convex mesh!) other than that. Since the entities are pushed into the render pipeline without knowing of any other already-rendered mesh, you can't avoid the cumulative blending when they overlap using the usual techniques. It's a lot trickier, so maybe you're not *that* interested in removing the cumulative blending.
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: Overlapping Transparencies

Post by Moohasha »

Okay, I followed Intermediate Tutorial 7 and figured out how to render my scene to a texture. Now I have two questions about how to procede:

1) How do I set the opacity of the rectangle? Do I have to do it to the RenderTexture? This might be something that I'd like to let the user change a runtime, so an easy, flexible method is desireable. If not, we can just make it static.

2) How do I render only specific entities to the texture and not the entire scene? I've only ever used one camera, one viewport, one render target, etc... This is all pretty new, but it looks like a very powerful technique so I'd like to figure it out.

Thanks for all the help.
Black holes are where God divided by 0
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: Overlapping Transparencies

Post by Moohasha »

I solved both problems and got it working. Here's my solution, if anyone is interested:

1) I made the render target transparent by simply making the material I apply to it transparent. Duh. In my test app, I just used scene_blend add because I was using the Black and White shader effect, but for my real app I'll need to get a little more clever.

2) All entities I wanted to be semi-transparent (ie, rendered to the texture), I set their visibility flag to VF_TRANS_ENT, some value I created. All other entities have the visibility flag VF_STATIC_ENT, just a different value. In preRenderTargetUpdate() and postRenderTargetUpdate() I just set the visibility mask of the scene manager to the appropriate flag based on when render target triggered the event. That way, when rendering to the scene, it only renders the static (non-transparent) entities, and when rendering to texture it only renders the desired (transparent) entities.

Not sure how this approach will scale for my real application, but at least I have something to go off of. Thanks for the help Kencho. Here's a screenshot of the results. I have 11 Ogre heads being rendered to the texture and then overlayed on the scene, and as you see the opacities don't add up. =)

Image
Black holes are where God divided by 0
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: Overlapping Transparencies

Post by Kencho »

Glad to see you got it working :D They're indeed powerful tools, so I hope you learned a lot from this experience :)
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: [Re-Opened] Overlapping Transparencies

Post by Moohasha »

Now I'm having two new issues which I didn't anticipate.

1) I thought this would be easy enough to avoid, but alas it has not been. How do I disable the sky box for a render target? I'm using visibility flags to determine what objects are visible in each render target, but this doesn't seem to affect the sky box. I even tried the following code and it didn't work.

Code: Select all

mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox");
Ogre::SceneNode::ObjectIterator itr = mSceneMgr->getSkyBoxNode()->getAttachedObjectIterator();
while (itr.hasMoreElements())
{
	// VF_MAIN_VP is the flag for objects that only render to the main viewport
	itr.getNext()->setVisibilityFlags(VF_MAIN_VP);
}
2) Objects I render to the texture are not culled by other objects in the scene, such as the ground or objects that are in front of it. Since the texture is just a full screen quad, then the semi-transparent objects just appear on top of everything else, like this:
Image

It should look like this, which I've accomplished by rendering the ground to texture as well (not desirable):
Image

Is there a way to use the depth buffer from one render target in another render target, so I can check the depth buffer of the main window when writing to texture to avoid writing over areas that should be culled?
Black holes are where God divided by 0
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 51

Re: [Re-Opened] Overlapping Transparencies

Post by madmarx »

1/ for the skybox, it is very easy. Select the viewport of your rendertexture, and then just call

myViewport->setSkiesEnabled(false);
// and I suppose you don't want overlays as well :
myViewport->setOverlaysEnabled(false);

2/ Not sure about this.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: [Re-Opened] Overlapping Transparencies

Post by Moohasha »

madmarx wrote:1/ for the skybox, it is very easy. Select the viewport of your rendertexture, and then just call

myViewport->setSkiesEnabled(false);
// and I suppose you don't want overlays as well :
myViewport->setOverlaysEnabled(false);
Ah, thank you. I figured it was something easy like that. Now I just need to figure out #2...

edit: fixed quote
Last edited by Moohasha on Tue Feb 17, 2009 10:51 pm, edited 2 times in total.
Black holes are where God divided by 0
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: [Re-Opened] Overlapping Transparencies

Post by Kencho »

For number two, you can create a scheme to each opaque material so that they write only to the depth buffer (there's an option for that... somethinkg like "colour_write false"; check the manual for the details), and use that scheme in that viewport. I'm not sure if you have an alpha channel in the RT though... :?
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: [Re-Opened] Overlapping Transparencies

Post by Moohasha »

I gave up on the Render-to-Texture technique. I has having too many issues with it.
I found a better solution using the stencil buffer. In the material script I add a pass before the main one with colour_write off so I only write to the depth buffer. For each entity, I add them to a special render queue group and when that group is rendered I use the following stencile buffer params:

rendersys->setStencilBufferParams(Ogre::CMPF_EQUAL, 1 ,0xFFFFFFFF, Ogre::SOP_REPLACE, Ogre::SOP_KEEP, Ogre::SOP_REPLACE, false);

The first pass that only writes to the depth buffer ensures that faces always get rendered in the right front-to-back order. The stencil buffer then makes sure I don't render over any area that's already been rendered by one of these semi-transparent objects.
And here are the results:

Image

Notice that you can see through each Ogre head, but the alpha values never add up. :D Thanks to everyone who helped/inspired.
Black holes are where God divided by 0
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Re: [Re-Solved] Overlapping Transparencies

Post by jacmoe »

Code, code, code! :D
Looks pretty cool. Like the undead army in Lord of the Rings.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: [Re-Solved] Overlapping Transparencies

Post by Kencho »

Ah, that's a pretty imaginative solution :) The results look great!
Image
User avatar
Moohasha
Gnoll
Posts: 672
Joined: Fri Dec 07, 2007 7:37 pm
x 8

Re: [Re-Solved] Overlapping Transparencies

Post by Moohasha »

Here's an example material script (for the ogre head, I had to modify the 4 material scripts used on that mesh):

Code: Select all

material TransparencyMaterial
{
	technique
	{
		pass
		{
			// Only write to the depth buffer
			colour_write off
		}

		pass
		{
			lighting off
			scene_blend alpha_blend

			// Lighting is baked into the vertices, so just use vertex colour
			ambient vertexcolour
		}
	}
}
And here's the RenderQueueListener that updates the stencil buffer:

Code: Select all

#define TRANSPARENT_GROUP 91

class TransparentQueueListener : public Ogre::RenderQueueListener
{
public:
   virtual void renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
   {
      //RenderQueue containing transparent objects
      if (queueGroupId == TRANSPARENT_GROUP)
      {
         Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem();

         rendersys->clearFrameBuffer(Ogre::FBT_STENCIL);
         rendersys->setStencilCheckEnabled(true);
         rendersys->setStencilBufferParams(Ogre::CMPF_EQUAL, 1 ,0xFFFFFFFF, Ogre::SOP_REPLACE, Ogre::SOP_KEEP, Ogre::SOP_REPLACE, false);
      }
   }

   virtual void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
   {
      if ((queueGroupId == TRANSPARENT_GROUP))
      {
         Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem();
         rendersys->setStencilCheckEnabled(false);
         rendersys->setStencilBufferParams();
      }
   }
};
All that's left is adding any entity you want to the proper render queue group:

Code: Select all

entity->setRenderQueueGroup(TRANSPARENT_GROUP);
Black holes are where God divided by 0