hlms template "alias" properties Topic is solved

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


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

hlms template "alias" properties

Post by bishopnator »

Hi, is it possible to set some properties within the hlms template files to the evaluation of an expression? Let's consider following simple approach:

  1. in onPreparePassHash I set a property "X" which defines shader behavior for all renderables
  2. in calculateHashForPreCreate I can override the property by setting "X_override" and "X_renderable"
  3. in hlms template file I use it as @property((X && !X_override) || X_renderable) .. @end

As I have multiple occurrences of this behavior, I need to repeat always the same expression. Instead of it I would like to do it in hlms template something @pset(useX, (X && !X_override) || X_renderable) and then later on @property(useX) .. @end but as far as I know, the value in @pset must be an integer or directly name of another property.

Note: I am aware, that I can do the evaluation in c++ directly in calculateHashForPreCreate, but I think doing it in the hlms should perform better because the output is cached - base on the set of input properties if there is already parsed shader, it is then used, instead of evaluating the hlms template files. Hence it is better to just set properties in c++ instead of doing some more complex logic with them.

Note2: in current state, I don't have access in calculateHashForPreCreate to the data which are available in onPreparePassHash (good example is SceneManager), so I have to set all the data through properties via setProperty calls and later in calculateHashForPreCreate I could potentially access the values through getProperty and set new properties - at the moment I would like to avoid getProperty calls there.

Note3: I checked the documentation of hlms and imagine that something like this might work:

Code: Select all

@psub(not_X_override, 1, X_override) // missing @pnot so assuming X_override is either 0 or 1, the @psub can calculate the negated value
@pmul(X_and_not_X_override, X, useX, not_X_override) // output is 0 or 1
@padd(useX, X_and_not_X_override, X_renderable) // output is 0, 1 or 2

But the code has 3 lines per a variable which seems just also too much :-( I would like to have it simple and readable - the code above is impossible to decode at the first look what the author would like to tell with it.

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

Re: hlms template "alias" properties

Post by dark_sylinc »

If I understood you correctly, you could set an Hlms template that is evaluated first(*) and then just do:

Code: Select all

@property( X && !X_override )
    @set( useX, 1 )
@end

(*)Order of template parsing is order in which templates are set in LibraryFoldersPaths (passed to Hlms constructor), and then within that folder, alphabetical name of each file.

Alternatively just override Hlms::notifyPropertiesMergedPreGenerationStep which was written to handle these sort of more complex logic (which was getting out of hand via Hlms syntax):

Code: Select all

if( getProperty( tid, "X" ) && !getProperty( tid, "X_override" ) )
    setProperty( tid, "useX", 1 );
User avatar
bishopnator
Gnome
Posts: 348
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 16

Re: hlms template "alias" properties

Post by bishopnator »

I went with setting the new properties within the template files and ensuring that this special template file is parsed always first. However, it still didn't work in my code and after long debugging I found out that the problem was with invalidation of the cached values in Renderable. When I set custom parameter to the Renderable after I already set datablock to it, the calculateHashForPreCreate is not called :-( Is it by design? What is the Ogre's recommended way of doing this? Let's consider that I have running scene and by a certain action I need to set custom parameter to the Renderable which should influence the creation of shaders.

At the moment I inject the code in my object (which can consist from multiple Ogre::Item instances):

Code: Select all

	.. set some custom parameters to the items via Ogre::Renderable::setCustomParameter(...)
	
// Invalidate the cache in Ogre::Renderable to force to recreate the shaders for the given datablock
for (auto* pItem : GetItems())
{
	for (size_t subItemIndex = 0; subItemIndex < pItem->getNumSubItems(); ++subItemIndex)
	{
		auto* pSubItem = pItem->getSubItem(subItemIndex);
		auto* pDatablock = pSubItem->getDatablock();
		pSubItem->_setNullDatablock();
		pSubItem->setDatablock(pDatablock);
	}
}

My expectation would be that Ogre does it automatically - when setCustomParameter is called, it invalidates the cache, but doesn't reevaluate it immediately (there can be multiple calls of setCustomParameter!). The evaluation (call of mHlmsDatablock->getCreator()->calculateHashFor) should be done later, when the cache values are actually needed ..

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

Re: hlms template "alias" properties

Post by dark_sylinc »

bishopnator wrote: Tue Jul 22, 2025 9:30 pm

When I set custom parameter to the Renderable after I already set datablock to it, the calculateHashForPreCreate is not called :-( Is it by design?

Yes, it's by lack of design. Or rather, Hlms doesn't really like stuff that could change per renderable at any time at any point (that is by design).

Hlms does not track custom parameters in particular.

What is the Ogre's recommended way of doing this?

I'm not sure. Your solution may actually be the right way; it's just that it feels awkward that it isn't encapsulated in prettier way (that would essentially do same thing).

HlmsDatablock::flushRenderables performs a very similar process when a material setting changes that requires invalidation:

Code: Select all

uint32 hash, casterHash;
if( !( *itor )->getHlmsHash() || !( *itor )->getHlmsCasterHash() )
{
  mCreator->calculateHashFor( *itor, hash, casterHash );
  ( *itor )->_setHlmsHashes( hash, casterHash );
}

But notice that flushRenderables() is called by HlmsPbsDatablock/HlmsUnlitDatablock whenever it is necessary.

PS: Regarding OllyBe's post. it looks generated by AI. "He" is also trying to post something regarding Ogre 14. Watching.

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

Re: hlms template "alias" properties

Post by bishopnator »

I wrote a helper function in my own code and it is working. I don't think that the custom parameter will change too often in the app, I just needed to react on those changes and it is pretty easy in the code to track those changes by myself.