[2.3] Alpha From Textures in Unlit Materials

Problems building or running the engine, queries about how to use features etc.
Post Reply
psysu
Halfling
Posts: 72
Joined: Tue Jun 01, 2021 7:47 am
x 6

[2.3] Alpha From Textures in Unlit Materials

Post by psysu »

Ogre Version: 2.3.0

Hi, I have a texture that is filled with alpha values as background.
Image

I used it on unlit material which renders it as black color wherever the background pixels of the texture are referred. Does unlit materials support alpha_from_textures feature like in pbs materials ?

Also, out of topic. How can i load textures from code ?. i have only managed to do it from .material script.

Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: [2.3] Alpha From Textures in Unlit Materials

Post by Lax »

Hi,

I can paste some code, how I load textures in my GameEngine:

Code: Select all

Ogre::String DatablockUnlitComponent::getUnlitTextureName(Ogre::HlmsUnlitDatablock* datablock, unsigned char textureIndex)
	{
		Ogre::TextureGpu* texture = datablock->getTexture(textureIndex);
		if (nullptr != texture)
		{
			return texture->getNameStr();
		}
		return "";
	}

void DatablockUnlitComponent::internalSetTextureName(unsigned char textureIndex, Ogre::CommonTextureTypes::CommonTextureTypes textureType, Variant* attribute, const Ogre::String& textureName)
	{
		Ogre::String previousTextureName = attribute->getString();
		// If the data block component has just been created, get texture name from existing data block
		Ogre::String tempTextureName = textureName;
		if (true == newlyCreated && nullptr != this->datablock)
		{
			tempTextureName = this->getUnlitTextureName(this->datablock, textureIndex);
		}

	attribute->setValue(tempTextureName);
	// Store the old texture name as user data
	if (false == tempTextureName.empty())
	{
		attribute->addUserData(tempTextureName);
	}

	this->addAttributeFilePathData(attribute);

	if (nullptr != this->datablock/* && false == newlyCreated*/)
	{
		// If no texture has been loaded, but still the data block has an internal one, get this one and remove it manually!
		if (true == attribute->getUserDataValue("OldTexture").empty())
		{
			tempTextureName = this->getUnlitTextureName(this->datablock, textureIndex);
			attribute->addUserData(tempTextureName);
			this->addAttributeFilePathData(attribute);
			// Retrieve the texture and remove it from data block
			tempTextureName = "";
		}

		// createOrRetrieveTexture crashes, when texture alias name is empty
		Ogre::String oldTextureName = attribute->getUserDataValue("OldTexture");
		if (false == oldTextureName.empty())
		{
			if (false == Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(oldTextureName))
			{
				Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_CRITICAL, "[DatablockUnlitComponent] Cannot set texture: '" + oldTextureName +
					"', because it does not exist in any resource group! for game object: " + this->gameObjectPtr->getName());
				attribute->setValue(previousTextureName);
				this->addAttributeFilePathData(attribute);
				return;
			}

			Ogre::TextureGpuManager* hlmsTextureManager = Ogre::Root::getSingletonPtr()->getRenderSystem()->getTextureGpuManager();
			// Attention: Which type here? for unlit?
			Ogre::TextureGpu* texture = hlmsTextureManager->createOrRetrieveTexture(oldTextureName, Ogre::GpuPageOutStrategy::Discard,
				textureType, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, 0); // Attention: Poolid = 0, is that correct?

			// hlmsTextureManager->getDefaultTextureParameters()[TEXTURE_TYPE_DIFFUSE].hwGammaCorrection = false

			if (nullptr != texture)
			{
				// Really important: GpuResidency must be set to 'OnSystemRam', else cloning a datablock does not work!
				if (texture->getResidencyStatus() != Ogre::GpuResidency::OnSystemRam)
				{
					try
					{
						texture->scheduleTransitionTo(Ogre::GpuResidency::OnSystemRam);
						texture->waitForData();
					}
					catch (const Ogre::Exception& exception)
					{
						Ogre::LogManager::getSingleton().logMessage(exception.getFullDescription(), Ogre::LML_CRITICAL);
						Ogre::LogManager::getSingleton().logMessage("[DatablockUnlitComponent] Error: Could not set texture: '" + oldTextureName + "' For game object: " + this->gameObjectPtr->getName(), Ogre::LML_CRITICAL);
						attribute->setValue(previousTextureName);
						attribute->setDescription("Texture location: '" + getResourceFilePathName(previousTextureName) + "'");
						return;
					}
				}

				// Invalid texture skip
				// Note: width may be 0, when create or retrieve is called, if its a heavy resolution texture. So the width/height becomes available after waitForData, if its still 0, texture is invalid!
				if (0 == texture->getWidth())
				{
					attribute->setValue(previousTextureName);
					this->addAttributeFilePathData(attribute);
					return;
				}

				// If texture has been removed, set null texture, so that it will be removed from data block
				if (true == tempTextureName.empty())
				{
					// Attention: Is that correct?
					hlmsTextureManager->destroyTexture(texture);
					texture = nullptr;
				}
// Attention: Here with index, instead of type and name, is that correct, and in pbsdatablockcomponent its done differently, check it!
					datablock->setTexture(textureIndex, oldTextureName);
				}
				else
				{
					attribute->setValue("");
					attribute->removeUserData("OldTexture");
				}
			}
		}
	}

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

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

Re: [2.3] Alpha From Textures in Unlit Materials

Post by dark_sylinc »

psysu wrote: Wed Aug 10, 2022 11:05 am

Does unlit materials support alpha_from_textures feature like in pbs materials ?

All Unlit materials force alpha_from_textures enabled. It's only Pbs materials that have the option to toggle it on/off

Are you having a particular problem?

psysu wrote: Wed Aug 10, 2022 11:05 am

Also, out of topic. How can i load textures from code ?. i have only managed to do it from .material script.

For textures used by Unlit this is enough:

Code: Select all

HlmsUnlitDatablock *unlitDatablock = ...;

TextureGpu *texture = textureManager->createOrRetrieveTexture(
                filename, GpuPageOutStrategy::Discard,
                TextureFlags::AutomaticBatching | TextureFlags::PrefersLoadingFromFileAsSRGB,
                TextureTypes::Type2D, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
unlitDatablock->setTexture( 0u, texture );

This was taken straight from HlmsUnlitDatablock::setTexture in Components/Hlms/Unlit/src/OgreHlmsUnlitDatablock.cpp

psysu
Halfling
Posts: 72
Joined: Tue Jun 01, 2021 7:47 am
x 6

Re: [2.3] Alpha From Textures in Unlit Materials

Post by psysu »

Are you having a particular problem?

Here's how the unlit material is rendered for the texture.

Image

if unlit materials are forced to use alpha_from_textures, the black pixels should be fully transparent right ?

Image

it should be rendering like this right ? i used "alpha_test greater 0.1" in the material to discard it

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

Re: [2.3] Alpha From Textures in Unlit Materials

Post by dark_sylinc »

Hi!

Can you post the material definition? It sounds like it may be something simple, like the material not using alpha blending.

psysu
Halfling
Posts: 72
Joined: Tue Jun 01, 2021 7:47 am
x 6

Re: [2.3] Alpha From Textures in Unlit Materials

Post by psysu »

material script i used for the mesh

Code: Select all

hlms CubeMat unlit
{    
diffuse_map CustomShape.png }
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Alpha From Textures in Unlit Materials

Post by dark_sylinc »

I think you're missing to tell Hlms to use alpha blending.

Either in script:

Code: Select all

hlms CubeMat unlit
{
    depth_write false // optional, but recommended for alpha blended geometry
    scene_blend alpha_blend
    diffuse_map CustomShape.png
}

Or in C++ code:

Code: Select all

HlmsBlendblock blendblock;
blendblock.setBlendType( SBT_TRANSPARENT_ALPHA );
mHlmsDatablock->setBlendblock( blendblock );

// START OPTIONAL (but recommended for alpha blended geometry)
HlmsMacroblock macroblock;
macroblock.mDepthWrite = false;  
mHlmsDatablock->setMacroblock( macroblock ); // END OPTIONAL
Post Reply