[2.1] @property across multiple pieces

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


Post Reply
DOS
Gnoblar
Posts: 19
Joined: Tue Oct 27, 2020 5:34 pm

[2.1] @property across multiple pieces

Post by DOS »

Hello,

to keep the HLMS templates more readable I wanted to try something like this:

Code: Select all

@piece( IF_NoDiffuseMap )
    @property( !diffuse_map && !diffuse_map0 )
@end
@piece( ELSE_NoDiffuseMap )
    @end
    @property( diffuse_map || diffuse_map0 )
@end
@piece( ENDIF_NoDiffuseMap )
    @end
@end
I thought I could use it then like so

Code: Select all

@insertpiece( IF_NoDiffuseMap )
    ... only run when there's a diffuse map ...
@insertpiece( ELSE_NoDiffuseMap )
    ... else do this ...
@insertpiece( ENDIF_NoDiffuseMap )
However, the preprocessor doesn't seem to evaluate the @property inside the piece as it prints both code blocks.
It works fine when I insert the definition of the pieces directly into the template.
The preprocessor can't do @property that is split up like this I presume? Is there a way around this?
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.1] @property across multiple pieces

Post by dark_sylinc »

You can try the following:

Code: Select all

@property( !diffuse_map && !diffuse_map0 )
    @set( IF_NoDiffuseMap, 1 )
@end

@property( IF_NoDiffuseMap )
@end
I'm not sure if that will work because of how @set and @property are evaluated (the order of evaluation).
But if you place them in different files, it will work because files are evaluated first in the order in which their folders were added to the library, and within the same folder files are parsed in alphabetical order:

Code: Select all

// 00.MySetup_piece_all.hlsl
@property( !diffuse_map && !diffuse_map0 )
    @set( IF_NoDiffuseMap, 1 )
@end

// PixelShader.hlsl
@property( IF_NoDiffuseMap )
@end
Or use math:

Code: Select all

// IF_NoDiffuseMap = diffuse_map + diffuse_map0
@padd( IF_NoDiffuseMap, diffuse_map, diffuse_map0 )

@property( IF_NoDiffuseMap )
@end
The difference between padd() and add() is that padd is always parsed first ignoring everything i.e. it will be executed even if inside @property( 0 ); which are ideal for setting things up without relying on separate files.

Valid math and pmath operations can be found in the code.

Note that @set( a, b && c ) is not supported.

Why this madness? Because Hlms parser syntax is not a proper language. It was written with parsing speed in mind (and honestly it went a bit overboard). I wanted to use Lua or Python but these languages suck at string parsing speed or as the case of python they add tremendous dependency overhead.
DOS
Gnoblar
Posts: 19
Joined: Tue Oct 27, 2020 5:34 pm

Re: [2.1] @property across multiple pieces

Post by DOS »

Ok, thanks for your answer. One more question regarding this: Is there any reason not to just write many smaller specific shaders so we don't have to use so much preprocessor logic?
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.1] @property across multiple pieces

Post by dark_sylinc »

DOS wrote: Thu Jun 03, 2021 10:29 am One more question regarding this: Is there any reason not to just write many smaller specific shaders so we don't have to use so much preprocessor logic?
You can create one shader per file, wrap it up in a single piece e.g. (you can even put the '@piece' inside comments so that it is a perfectly valid raw shader file):
// @piece( FileA )
... your code here ...
// @end
then decide in C++ (via Hlms::mPieces) or with script syntax (yuck! That'd be an if/else ladder) which piece to select (e.g. which @insertpiece to use) in VertexShader_vs and PixelShader_ps

I already tried having many smaller specific shaders. It doesn't scale. There's a lot of boilerplate code that, when it needs to change, you need to change a lot of them. Same happens with code that is shared for a lot of these shaders.

Take in mind if each feature can be toggled on / off and each feature is a shader, the number of shaders to write is 2ⁿ.
Meaning for 4 different features you need 16 shaders. It doesn't scale.

You may have 2 or 3 shaders in mind so it makes perfect sense to you (KISS!), but from an engine perspective where users can have an arbitrary combination of settings, it's impossible to track of.

Cheers
Post Reply