Binding compositor textures in scene pass Topic is solved

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


User avatar
bishopnator
Gnome
Posts: 379
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 18

Binding compositor textures in scene pass

Post by bishopnator »

The quad pass has support for assigning the textures via CompositorPassQuadDef::addQuadTextureSource where it is possible to specify texture unit and texture name. Together with mExposedTextures it is possible to process the information in the HLMS and setup the binding correctly and without any hard-coded relation to specific quad passes.

However in scene pass, I don't see such support. I have a scene pass A which renders to 2 textures and then next scene pass B which should bind the already rendered 2 textures and use them in a pixel shader for all the renderables. At the moment I see 2 options:

  • inherit the CompositorPassSceneDef and CompositorPassScene and add the similar support for the texture sources as in quad pass and process the pass in the HLMS (general way, but more typing to implement the classes, however the HLMS implementation would be simpler)
  • use custom identifiers and access them in HLMS and hard-code the binding there for each identifier separately (reusing already existing ogre classes, but the HLMS implementation is uglier)

Is there any built-in support in Ogre to do some "automatic" bindings of the rendered textures?

Just for a reference, for the quad passes, I wrote in my HLMS following code, which could be reused, if texture sources are available for scene pass as well:

Code: Select all

// Get the current compositor pass.
if (const auto* pCompositorPassQuad = dynamic_cast<const CompositorPassQuad*>(mCurrentSceneManager->getCurrentCompositorPass()); pCompositorPassQuad != nullptr)
{
	// Bind the textures from the CompositorPassQuad.
	const auto& sceneManagerCompositorTextures = mCurrentSceneManager->getCompositorTextures();
	const auto* pCompositorPassQuadDef = static_cast<const CompositorPassQuadDef*>(pCompositorPassQuad->getDefinition());
	for (const auto& textureSource : pCompositorPassQuadDef->getTextureSources())
	{
		// Find the compositor texture.
		const auto found = std::find(sceneManagerCompositorTextures.begin(), sceneManagerCompositorTextures.end(), textureSource.textureName);
		if (found == sceneManagerCompositorTextures.end())
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Invalid compositor texture!", "HlmsTech::fillBuffersFor");

	// Set binding type. The compositor textures are bound always just to pixel shaders.
	if (mRenderSystem->getCapabilities()->hasCapability(RSC_COMPLETE_TEXTURE_BINDING))
		mRenderSystem->_setBindingType(TextureUnitState::BT_FRAGMENT);

	// Set the texture to the render system.
	mRenderSystem->_setTexture(textureSource.texUnitIdx, found->texture, false);
}
}
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5571
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1405

Re: Binding compositor textures in scene pass

Post by dark_sylinc »

There's no automated method due to the complexity involved in HlmsPbs (it's not crazy complex, but it's not a one-liner either. Simply no one requested it).

Pass definitions have CompositorPassDef::mExposedTextures so that the compositor can take care of the layout transitions (e.g. Vulkan and in some cases, OpenGL). But binding the texture to the material (or globally via HlmsPbs) needs to be done by hand.

User avatar
bishopnator
Gnome
Posts: 379
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 18

Re: Binding compositor textures in scene pass

Post by bishopnator »

I am implementing CompositorPassProvider class with my customized CompositorPassScene/CompositorPassSceneDef where I am adding member of TextureSources copied from CompositorPassQuadDef. I am not using the "global" prefix, but I spot there in CompositorPassQuadDef::addQuadTextureSource that in the case of this special prefix, the texUnitIdx is not used and instead there is hard-coded 0 --> is it ok or bug?

Code: Select all

    void CompositorPassQuadDef::addQuadTextureSource( size_t texUnitIdx, const String &textureName )
    {
        if( textureName.find( "global_" ) == 0 )
        {
            mParentNodeDef->addTextureSourceName( textureName, 0,   /// <------ THIS ZERO I MEAN
                                                  TextureDefinitionBase::TEXTURE_GLOBAL );
        }
        mTextureSources.push_back( QuadTextureSource( texUnitIdx, textureName ) );
    }

If addQuadTextureSource is called twice with different texture names, but both will have global prefix, an exception is thrown.

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

Re: Binding compositor textures in scene pass

Post by dark_sylinc »

The "0" looks correct at first glance. That number is for what channel of the input nodes, but global textures do not have channels. Thus any number should do.

But if that causes an exception, that sounds like a bug.

In retrospective global textures were a mistake. They are barely used, when they are used it ends up unmasking bugs (because it's a barely-tested path), and everything that a global texture can do, could also be implemented as a texture created a workspace level (like global textures) but then inserted as a input channel like any other regular texture (so that all textures follow the same codepath).

You can literally "emulate" this behavior by creating textures yourself, add them as external textures to the workspace, and connect them normally through channels (in fact this is a very useful pattern because it lets you have "global" textures that are shared across multiple workspaces).

User avatar
bishopnator
Gnome
Posts: 379
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 18

Re: Binding compositor textures in scene pass

Post by bishopnator »

Ok, I actually didn't verify whether there is an exception. Looking in the code looks that it could throw, but probably not due to using this index 0.

Anyway, I am using exactly textures like you pointed out - creating them outside of the workspaces and then connecting them through the input channels and sharing them between multiple workspaces as needed.