Simple Shader with HLMS

Problems building or running the engine, queries about how to use features etc.
Post Reply
ds80
Gnoblar
Posts: 3
Joined: Sun Sep 17, 2017 7:42 pm

Simple Shader with HLMS

Post by ds80 »

Hi all,
I am new to Ogre and have a question about making a new shader based off the Unlit HLMS. I am planning on implementing a multi-channel signed distance field (MSDF) operation for rendering text. Basically, I will draw 2 triangles to make a quad then render the text onto it from a MSDF texture atlas. There won't be any lights so I am assuming, based on what I've read, that the Unlit shader is the way to go. My question though is how do I go about adding the shader code I need? I've read about preprocessor directives and I've seen the .glsl files for Unlit.

Also, if I want to add some custom attributes to the Unlit shader or have different variations of it, what is the best way to go about it? (i.e. Unlit shader for different objects with different maps.)

Thanks!
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: Simple Shader with HLMS

Post by dark_sylinc »

ds80
Gnoblar
Posts: 3
Joined: Sun Sep 17, 2017 7:42 pm

Re: Simple Shader with HLMS

Post by ds80 »

Ok, so I think I am following along with the @piece stuff, but what I don't want every object to utilize the @piece that I customize? I would imagine there must be a switch on the C++ side to either include or not include the custom piece since as far as I understand everything gets loaded when the program starts.
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: Simple Shader with HLMS

Post by dark_sylinc »

Hi!

You can wrap around the definition of the piece around a property like this:

Code: Select all

@property( my_shiny_feature )
@piece( custom_vs_something )
    //Code here
@end
@end
And then from C++ use HlmsListener::preparePassHash add the property via hlms->_setProperty( "my_shiny_feature", 1 );
This lets you toggle features per pass.
Unfortunately at this moment if you want to override this feature per object or per material you'll need something more than just HlmsListener (i.e. subclassing HlmsPbs or create a PR extending HlmsListener)
ds80
Gnoblar
Posts: 3
Joined: Sun Sep 17, 2017 7:42 pm

Re: Simple Shader with HLMS

Post by ds80 »

dark_sylinc wrote:Hi!

You can wrap around the definition of the piece around a property like this:

Code: Select all

@property( my_shiny_feature )
@piece( custom_vs_something )
    //Code here
@end
@end
And then from C++ use HlmsListener::preparePassHash add the property via hlms->_setProperty( "my_shiny_feature", 1 );
This lets you toggle features per pass.
Unfortunately at this moment if you want to override this feature per object or per material you'll need something more than just HlmsListener (i.e. subclassing HlmsPbs or create a PR extending HlmsListener)
Awesome! Thanks for the quick replies! Now for the $1,000,000 question....performance. From what I've read the way you have the PBS and Unlit shaders setup is for performance reasons (i.e. state changes). Essentially me writing my own implementation and switching back and forth would kind of defeat that optimization correct? It would be like using the old material system?
hyyou
Gremlin
Posts: 173
Joined: Wed Feb 03, 2016 2:24 am
x 17
Contact:

Re: Simple Shader with HLMS

Post by hyyou »

Custom HLMS is the way of life. Only 1 custom HLMS is more than enough!
It can do PBS, Unlit, ... everything... all in one with the holy @piece manipulation.
Every morning, I praise the one(s) that invent @piece and HLMS syntax.

My HLMS can render text with custom UV coordinate (even with Forward3D light). It is very flexible.
This is a great unofficial tutorial : http://www.ogre3d.org/forums/viewtopic.php?f=25&t=83763 .
Disclaimer : it is very hard to learn, but once you grasp the idea, it is not too hard anymore.

Here is my understanding after playing with custom HLMS. Please fix me if my practice is wrong.

HLMS::preparePassHash()
- is called once per time-step.

HLMS::calculateHashForPreCreate(Ogre::Renderable* renderable,Ogre::PiecesMap* inOutPieces)
- is called once per 1 Ogre::item - usually only once when initialize at item->setDatablock().

I call setProperty() inside HLMS::calculateHashForPreCreate() to control @piece in per-item level.
I call datablock->flushRenderables() to recompile HLMS->GLSL whenever I think glsl code should be changed.

The byte buffer for @piece (if any) have to be consistent with HLMS::fillBuffersFor().
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Simple Shader with HLMS

Post by IndieGuy11 »

I have a thread on this over at: http://www.ogre3d.org/forums/viewtopic.php?f=25&t=93495

Once I am able to get a working bare bones example (for DX11), I will post my code.

Until then we are pretty much on our own unless the advanced users (who already grasp the concept) want to spare some bones. The example you posted too was intended for OpenGL, and since then some things have changed a bit.

Its a shame because if there was a simple less invasive example on how to do this im sure the community would appreciate and see how powerful Ogre Is. :P
Post Reply