Page 1 of 1

Alpha cleared with 1 instead of 0.

Posted: Sun Aug 16, 2009 8:01 am
by mkultra333
In my quasi-deferred shading engine one pass is using the alpha channel of an RGBA texture to hold data. I want that texture cleared every render frame, and I want the alpha cleared to zero. The data gets added several times per frame using blendmode add. Here's some code.

Code: Select all

	Ogre::ColourValue ClearColour = Ogre::ColourValue(0,0,0,0) ; // need to clear alpha as well.

	...

	renderTexture_DSShadow = RTT_Texture_DSShadow->getBuffer()->getRenderTarget();
	renderTexture_DSShadow->addViewport(m_pCamera);
	renderTexture_DSShadow->getViewport(0)->setClearEveryFrame(true);
	renderTexture_DSShadow->getViewport(0)->setBackgroundColour(ClearColour);
	renderTexture_DSShadow->getViewport(0)->setOverlaysEnabled(false);
But instead, the alpha channel always starts cleared with a value of 1 instead of 0. So when I write 0.5 to it (blend mode add), I get an output of 1.5.

Do alpha channels have to be cleared in some special way? Or have I done something wrong in the above code?

Re: Alpha cleared with 1 instead of 0.

Posted: Sun Aug 16, 2009 12:18 pm
by nullsquared
Are you sure it *has* an alpha channel? And is it a part of an MRT or is it a standalone RTT? I clear alpha to 0 all the time here and it works fine (although I do it manually with RenderSystem::clearFrameBuffer)

Re: Alpha cleared with 1 instead of 0.

Posted: Sun Aug 16, 2009 2:02 pm
by mkultra333
Yeah, it definitely has an alpha channel because my current work around is use ( colour.a - 1.0 ) instead of ( colour.a ). The alpha accumulates its data fine, just that it starts at 1.0 instead of 0.0. No MRT, just an RTT.

The clearing is just the automatic process set up in the code above.

Re: Alpha cleared with 1 instead of 0.

Posted: Sun Aug 16, 2009 2:42 pm
by nullsquared
Something's going wrong, then. Does getClearColour() return the colour with the correct alpha?

Re: Alpha cleared with 1 instead of 0.

Posted: Mon Aug 17, 2009 3:06 am
by mkultra333
I'm not using compositors so I used renderTexture_DSShadow->getViewport(0)->getBackgroundColour() ; and it came out correct, I tested with other values and it was fine.

This highlighted more weirdness, since changing the background colour made no difference either. RGB get set to 0, alpha gets set to 1, regardless of the values I put in for ClearColour. I should probably point out that this surface is the output of my shadow pass, using code derived from the soft shadows demo. Perhaps automated shadow rendering does its own thing as far as clearing the texture goes.

The setup is just to additively apply the shadow lighting passes, with the assumption that automated clearing has taken place. Maybe my shaders are just screwy, although I would expect much more scrambled results in that case, instead of a clean 0,0,0,1 clear of the surface followed by normal reading and writing to texture.

I don't want to get stuck here, there's an easy workaround. I just set it to clear as (0,0,0,1) because that's what it's doing anyway, then adjust by -1 when I read from the alpha channel. Still, weird and a little disconcerting, don't know if it is my error or Ogre's.

Re: Alpha cleared with 1 instead of 0.

Posted: Mon Aug 17, 2009 3:28 am
by nullsquared
I honestly don't know what to tell you. If you really need to get it to clear to the right colour, you can always do it manually:

Code: Select all

renderSys->_setViewport(viewport);
renderSys->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue(r, g, b, a)); // might want to | Ogre::FBT_DEPTH if you need to clear that too

Re: Alpha cleared with 1 instead of 0.

Posted: Mon Aug 17, 2009 3:42 am
by mkultra333
I just gave that a shot, but remembered I'd tried that before back when I was trying to manually render the shadows. It produces very glitchy results, especially now that I'm back to using automatic shadow code. Only part of the screen gets cleared, and you can see artifacts from the rendered shadow maps in it.

I'm 66% confident this is an automatic shadow code thing, as opposed to my own coding, so hopefully my workaround will suffice. I use the manual method to clear other textures and it works fine, just not on the surface that uses shadows.

Edit: Here's the code I used

Code: Select all

renderTexture_DSShadow->getViewport(0)->setClearEveryFrame(false);

...

		m_pRoot->getRenderSystem()->_setViewport(renderTexture_DSShadow->getViewport(0)) ;
		m_pRoot->getRenderSystem()->clearFrameBuffer(Ogre::FBT_COLOUR|Ogre::FBT_DEPTH, Ogre::ColourValue(1, 0, 0, 0)); 
		renderTexture_DSShadow->update(true) ;
The red 1 was just a test to see if it was having an effect. I just realized the area cleared is only equal to the size of the shadow maps. So if shadow maps are 512x512, then only 512x512 of the screen gets cleared, and has shadow glitches on it. Not only that, but the area outside the "shadow map" range is cleared as usual, (0,0,0,1), even though automatic clearing is turned off.