RibbonTrail / billboard blocks glow compositor [solved]

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
User avatar
Senzin
Halfling
Posts: 57
Joined: Wed Apr 06, 2011 8:54 pm
x 3

RibbonTrail / billboard blocks glow compositor [solved]

Post by Senzin »

I'm using the glow compositor on the Wiki. In the attached screenshot, you can see the wall panels glowing blue. On the right you can see a ribbon trail flying by. As it crosses in front of the glowing panels, it blocks the effects from the compositor.

Here is the material for the ribbon trail:

Code: Select all

material Laser
{
	technique
	{
		pass
		{
			lighting off
			scene_blend add
			depth_write off
			diffuse vertexcolour

			texture_unit
			{
				texture laserBand.png 1d
				tex_address_mode clamp
				filtering none
			}
		}
	}
}
I tried setting the material to alpha_blend instead of add (and adding an alpha channel of course). The alpha channel did work, adding the fade out effects on the sides, however, it still blocked the compositor glow (and didn't look nearly as good anyway).

The manual says that compositors default to a render queue range of RENDER_QUEUE_SKIES_EARLY=5 to RENDER_QUEUE_SKIES_LATE=95. So I tried setting the ribbon trail to RENDER_QUEUE_OVERLAY=100, thinking they would render after the glow effect had been applied, but nothing seemed to change. I also tried RENDER_QUEUE_MAX=105, but then it just disappeared.

Finally, in a last ditch effort, I decided to set the compositor to stop after RENDER_QUEUE_MAIN=50 and set the ribbon trail to RENDER_QUEUE_6=60. This fixed the problem!

Code: Select all

// src.cpp
mRibbon->setRenderQueueGroup(RENDER_QUEUE_6);

// glow.compositor
pass render_scene
{
	last_render_queue 50
}
That's why I'm posting this as solved. But the reason I'm posting it at all is two fold:
1. So someone running into this problem will find their solution faster.
2. Because I'm still confused about why setting the ribbon to queue 100 didn't work since the compositor defaults to 95 according to the manual. And why did the ribbon just disappear when set to 105? Can anyone explain this?
laser.jpg
laser.jpg (217.67 KiB) Viewed 2129 times
x3n
Gnoblar
Posts: 7
Joined: Mon Jun 16, 2008 1:59 am
Location: Zurich
x 3
Contact:

Re: RibbonTrail / billboard blocks glow compositor [solved]

Post by x3n »

Today I ran into the same problem and I was glad to find your post.
However, for me this solution was not suitable because (in contrast to you) I wanted the glow effect to apply also to the ribbon-trails (as well as to particle-effects and other billboards). Also I did not like the idea of tampering with render queues, at least not at this stage of my project.

I found a different solution which is not optimal either, but it works pretty well for my setup.

It's important to understand how the glow effect works. It uses a specific material scheme called "glow" to draw a glow-map of the scene (which is then blurred and added to the original scene). For every material, there are two possibilities:
a) It contains a technique for the material scheme "glow" -> the technique is used to draw the material to the glow map
b) It does not contain a suitable technique -> the material is painted with an opaque black to the glow map (the black material is defined in GlowMaterialListener.h)

The problem is: The ribbon-trail doesn't define a "glow" technique, thus it is rendered as an opaque black material to the glow-map which means that the glowing background is hidden behind the ribbon-trail.

In other words: Even though the ribbon-trail's material is transparent in the real scene, the fallback-material that is used for the glow map is NOT transparent.

There are two possible solutions:
1) Define a "glow" technique for the ribbon-trail's material (and every other transparent material). The glow-technique must be transparent itself as well, otherwise it will still block the glow effect.
2) Enhance GlowMaterialListener.h to use a transparent fallback-material if the original material is transparent.

For the moment I went with solution (2) because I did not want to modify all transparent materials in my project. Maybe I'll change that in the future because I feel like solution (1) offers more control over the rendered scene.

Anyway, here's how GlowMaterialListener looks for solution 2:

Code: Select all

    class GlowMaterialListener : public Ogre::MaterialManager::Listener
    {
        public:
            GlowMaterialListener()
            {
                mBlackMat = Ogre::MaterialManager::getSingleton().create("mGlowBlack", "Internal");
                mBlackMat->getTechnique(0)->getPass(0)->setDiffuse(0,0,0,0);
                mBlackMat->getTechnique(0)->getPass(0)->setSpecular(0,0,0,0);
                mBlackMat->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
                mBlackMat->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,0);

                mTransparentMat = Ogre::MaterialManager::getSingleton().create("mGlowTransparent", "Internal");
                mTransparentMat->getTechnique(0)->getPass(0)->setDiffuse(0,0,0,0);
                mTransparentMat->getTechnique(0)->getPass(0)->setSpecular(0,0,0,0);
                mTransparentMat->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
                mTransparentMat->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,0);
                mTransparentMat->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_ADD);
                mTransparentMat->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
            }

            Ogre::Technique* handleSchemeNotFound(unsigned short, const Ogre::String& schemeName, Ogre::Material* mat, unsigned short, const Ogre::Renderable*)
            {
                if (schemeName == "glow")
                {
                    // try to figure out if the original material is transparent. if yes, use a black transparent material, otherwise a black opaque one.
                    if (mat->isTransparent())
                        return mTransparentMat->getTechnique(0);
                    else
                        return mBlackMat->getTechnique(0);
                }
                return NULL;
            }

        private:
            Ogre::MaterialPtr mBlackMat;
            Ogre::MaterialPtr mTransparentMat;
    };
I hope this helps someone.
Post Reply