Blackened pixels due to filtering problem

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Nickak2003
Goblin
Posts: 272
Joined: Thu Jun 10, 2004 4:19 am
x 26

Blackened pixels due to filtering problem

Post by Nickak2003 »

Hello, I have a manual image which I am rendering to screen. This image is square, but some pixels should not be rendered, and are therefore alpha=0. This seems to work. The problem is that the filtering is blending these pixels (black+transparent) into the colored visible pixels, darkening them. I tried disabling filtering like so:

Code: Select all

	void createDataBlock(Graphics& graphics) {

	static std::size_t idCounter = 0;

	Ogre::HlmsManager* hlmsManager = graphics.getRoot()->getHlmsManager();

	Ogre::HlmsUnlit* hlmsUnlit = static_cast<Ogre::HlmsUnlit*>(hlmsManager->getHlms(Ogre::HLMS_UNLIT));

	Ogre::HlmsMacroblock macroBlock;
	macroBlock.mDepthCheck = false;
	Ogre::HlmsBlendblock blendBlock;
	blendBlock.setBlendType(Ogre::SceneBlendType::SBT_TRANSPARENT_ALPHA);

	mName = "ManualTextureBox" + std::to_string(idCounter++);

	mDataBlock = static_cast<Ogre::HlmsUnlitDatablock*>(
		hlmsUnlit->createDatablock(mName,
			mName,
			macroBlock,
			blendBlock,
			Ogre::HlmsParamVec()
		));

	mDataBlock->setTexture(0, mManualTexture.getTexture());

	Ogre::HlmsSamplerblock samplerblock;
	samplerblock.mU = Ogre::TextureAddressingMode::TAM_WRAP;
	samplerblock.mV = Ogre::TextureAddressingMode::TAM_WRAP;
	samplerblock.mW = Ogre::TextureAddressingMode::TAM_WRAP;
	samplerblock.mMaxAnisotropy = 0;
	samplerblock.mMagFilter = Ogre::FO_NONE;
	samplerblock.mMinFilter = Ogre::FO_NONE;
	samplerblock.mMipFilter = Ogre::FO_NONE;
	samplerblock.setFiltering(Ogre::TextureFilterOptions::TFO_NONE);

	mDataBlock->setSamplerblock(Ogre::TextureTypes::Type2D, samplerblock);
}

However, this does not work. This is what the troublesome area of the image looks like:
https://pasteboard.co/PKjyGzE7V3eH.png

How can this be resolved?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5477
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1359

Re: Blackened pixels due to filtering problem

Post by dark_sylinc »

What you're experiencing is solved using premultiplied alpha blending.

The algorithm consists in multiplying your texture rgb * a before saving to disk (or to RAM); and then setting the blend type to:

Code: Select all

blendblock.mSourceBlendFactor = Ogre::SBF_ONE;
blendblock.mDestBlendFactor = Ogre::SBF_ONE_MINUS_SOURCE_ALPHA;
blendblock.mSourceBlendFactorAlpha = blendblock.mSourceBlendFactor;
blendblock.mDestBlendFactorAlpha = blendblock.mDestBlendFactor;

But as the blog post describes, there are other side effects and it's a different mindset (because alpha = 0 no longer means "fully transparent", fully transparent is achieved when both rgb = 0 and alpha = 0)

Nickak2003
Goblin
Posts: 272
Joined: Thu Jun 10, 2004 4:19 am
x 26

Re: Blackened pixels due to filtering problem

Post by Nickak2003 »

OK, these textures are manually generated each frame, using code like:

Code: Select all

*reinterpret_cast<uint32_t* RESTRICT_ALIAS>(texBox.at(x, y, 0)) = v;

I guess I don't quite understand what you mean by "multiplying your texture rgb * a before saving to disk (or to RAM)".
Is all I need to do is change the blend block and maintain alpha == 0 and color == 0 to get the desired effect?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5477
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1359

Re: Blackened pixels due to filtering problem

Post by dark_sylinc »

Then you need to do:

Code: Select all

col.r *= col.a;
col.g *= col.a;
col.b *= col.a;
v = col.getAsRGBA(); //or getAsABGR or whatever
*reinterpret_cast<uint32_t* RESTRICT_ALIAS>(texBox.at(x, y, 0)) = v;

And set the blendblock to the mode I described above.

Nickak2003
Goblin
Posts: 272
Joined: Thu Jun 10, 2004 4:19 am
x 26

Re: Blackened pixels due to filtering problem

Post by Nickak2003 »

My friend, this does not appear to be working out, it is still darkening. Here are my various code segments:

Code: Select all

		Ogre::HlmsManager* hlmsManager = graphics.getRoot()->getHlmsManager();

	Ogre::HlmsUnlit* hlmsUnlit = static_cast<Ogre::HlmsUnlit*>(hlmsManager->getHlms(Ogre::HLMS_UNLIT));

	Ogre::HlmsMacroblock macroBlock;
	macroBlock.mDepthCheck = false;
	Ogre::HlmsBlendblock blendBlock;
//	blendBlock.setBlendType(Ogre::SceneBlendType::SBT_TRANSPARENT_ALPHA);

	blendBlock.mSourceBlendFactor = Ogre::SBF_ONE;
	blendBlock.mDestBlendFactor = Ogre::SBF_ONE_MINUS_SOURCE_ALPHA;
	blendBlock.mSourceBlendFactorAlpha = blendBlock.mSourceBlendFactor;
	blendBlock.mDestBlendFactorAlpha = blendBlock.mDestBlendFactor;

	mName = "ManualTextureBox" + std::to_string(idCounter++);

	mDataBlock = static_cast<Ogre::HlmsUnlitDatablock*>(
		hlmsUnlit->createDatablock(mName,
			mName,
			macroBlock,
			blendBlock,
			Ogre::HlmsParamVec()
		));

	mDataBlock->setTexture(0, mManualTexture.getTexture());

each frame, the following code is called for each pixel:

Code: Select all

				color.setAsABGR(Ogre::ABGR(mConvertedWeights[i]));

			//premulitply alpha to prevent transparnt-black from blending affecting output layer
			color.r *= color.a;
			color.g *= color.a;
			color.b *= color.a;

			*reinterpret_cast<uint32_t* RESTRICT_ALIAS>(texBox.at(x, y, 0)) = color.getAsABGR();

I have verified that the pixels which should be black are indeed argb == 0.

the texture, which is attached to a manual object ( quad + identiy view/proj), is created with this flag:

Code: Select all

Ogre::PixelFormatGpu::PFG_RGBA8_UNORM_SRGB
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5477
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1359

Re: Blackened pixels due to filtering problem

Post by dark_sylinc »

Maybe I understood incorrectly what you're trying to achieve? Could you post in Photoshop/GIMP what you were hoping to achieve?