Hi!
We have an entry in the 2.1+ FAQ regarding custom Hlms implementations.
In the master (4.0) branch we've added tutorials on writing custom Hlms implementations. See Tutorial_Hlms01 through Tutorial_Hlms05.
These tutorials apply to OgreNext 3.0 too. Maybe a virtual function override changed signature parameter, but it should be easy enough to adapt.
Now, onto your question:
haloman30 wrote: Wed May 21, 2025 2:11 am
however, all the posts and topics I've found seem to not quite be in reference to the kind of system I'm looking for - which is, to allow totally any number of arbitrary pixel/vertex/geometry shaders to be authored by users.
The Hlms is very flexible; so you can define custom pieces per object (i.e. apply custom shader code to a particular object), per material, or per pass.
You can apply different pieces to different objects; effectively creating an arbitrary number of shaders by users (though you'd probably have to write something on top to manage your users' shader code -> map into what goes into which object). See the tutorial.
In the master/4.0 branch we've also added a new per-material setting HlmsDatablock::setCustomPieceFile (with material JSON support keyword "custom_piece_file_vs" and co.) which allows registering a custom piece file per material without C++ additional code.
When customizing existing Hlms implementations you can do things like:
Code: Select all
@undefpiece( DeclareBRDF )
@piece( DeclareBRDF )
// your lighting code here
@end
To force the PBS component of Hlms to not generate its lighting code and use whatever customization you want.
It seems that you want a shader to start from scratch (rather than customize an existing one). That is also possible.
This is often not recommended because Unlit & Pbs deal with a lot of boilerplate (skeletal animation, shadow casting, etc) so customizing these instead of starting from scratch is usually the easiest path. Specially since you can override this code to do whatever else.
For example Terra from the Terrain Sample completely overrides the vertex & pixel shaders of HlmsPbs while still reusing a lot of individual pieces of code from HlmsPbs.
haloman30 wrote: Wed May 21, 2025 2:11 am
So - is this correct? Or am I mistaken? If not, is there any significant overhead or limits on the number of HLMSes? Or is there some other solution that I've just missed?
If you mean HLMS types, we support 8 (with LowLevel, Pbs and Unlit taking away 3, so you're left with 5). However for what you want to implement, you'd want to either customize HlmsPbs/HlmsUnlit, or create an extra Hlms type (assuming that you want users to code from scratch) that manages all user's shader code.
This is what HlmsLowLevel essentially does, it looks at what was defined in the older Material system from v1 Ogre and creates the shaders from it. So if the user creates a thousand different shaders using the v1 material system, the HlmsLowLevel will create a thousand shaders.
A single Hlms type can create a virtually unlimited number of shaders.
haloman30 wrote: Wed May 21, 2025 2:11 amis there any significant overhead or limits on the number of HLMSes?
Originally the v1 Material system was very slow and unsupported in regular rendering because it was treated as an exception; but those issues were fixed and nowadays the main reason to discourage users from using the v1 Material system for thousands of objects is that its flexibility and ease of use (user-friendly) design goals clash with high performance.
High performance originates from code that can perform assumptions, attempts to treat lots of objects in the same way, and imposes specific limitations on what can be done and what cannot. I'm not talking about OgreNext here, but computers in general.
But "cost" is a relative term here. Applying v1 materials on 100 Items is probably going to be fine on a modern CPU.
But if you apply it on many thousands of them, you won't have the same performance as you'd have with HlmsPbs or Unlit because they have limitations on their interfaces to achieve greater efficiency.
If what you want are shaders from scratch, a custom Hlms type may be what you're looking for; but you may just end up reinventing the v1 Material System (with similar performance pitfalls).
Cheers