Extending the material attribute set

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Extending the material attribute set

Post by Nir Hasson » Tue Sep 08, 2009 9:00 am

Hi -

During my current work on the RT Shader System component I encountered a new situation where I need to extend the current material attributes set.
For example: There is no way I can know now whether or not I should use a per pixel lighting model on a certain material.
I also plan to implement a normal map support as one of the core features of the RT Shader System. In that case I'll have to supply additional properties on per material basis – the normal map, normal scale etc.

I see three possible solutions to achieve that –

1. Adding hard coded attribute for each aspect I need. I.E – a material script will include attribute lighting_per_pixel. It will explicitly cause the RT Shader System to generate equivalent pass with per pixel light model.
The pros are – simple, straightforward solution.
The cons are – limited to the RT Shader System only.

2. Add option to add custom attributes - like many other file formats that allow the user to extend their structure.
The pros are – flexible, any further extension is free of code writing, might be useful for other custom user usages.
The cons are – might cause to some conflicts if the same name is used for different aspects.

3. Allow sub classing the Pass class. In that case one can add its own custom attributes for each pass and take care of all aspects of serialization.
The pros are – won't affect any other Ogre users, the custom developer responsible for it and can't hurt anyone else.
The cons are – demand massive changes to the core of material system, the sub class pass code won't be useful for other users.

I'd like to hear any other suggestions/comments before I'll continue working in that direction… :D
0 x

User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany

Re: Extending the material attribute set

Post by xadhoom » Tue Sep 08, 2009 10:26 am

My first thought is that it can be really confusing when mixing material parameters with those which are used (and only used) by the RT Shader System component.
Did you think about just providing your own material script files (e.g. "*.rtsm") which uses its own dedicated syntax and allows you all the flexibility you want and won´t confuse any (especially newbie) user when starting with material scripts? A clean cut between both approaches...

Just my 2 cents...

xad

EDIT: Or do want to link usual materials and rts materials together tightly?
0 x

User avatar
haffax
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4823
Joined: Fri Jun 18, 2004 1:40 pm
Location: Berlin, Germany
Contact:

Re: Extending the material attribute set

Post by haffax » Tue Sep 08, 2009 10:56 am

Whether or not to do per-pixel-lighting can be derived from the shading pass attribute.

As for the hint about the texture content, there already is content_type attribute in texture unit. Though its current usage doesn't map to what you want to do, it could be changed to have a second optional parameter that is evaluated in case the first one is named.
E.g. like

Code: Select all

...
texutre_unit
{
    texture my_normal_map.png
    content_type named normal_map_signed
}
But....
This is really hard to do for the general case. I see this feature growing and outgrowing this simple solution.
0 x
team-pantheon programmer
creators of Rastullahs Lockenpracht

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Re: Extending the material attribute set

Post by Assaf Raman » Tue Sep 08, 2009 11:28 am

Nir Hasson wrote:...
3. Allow sub classing the Pass class. In that case one can add its own custom attributes for each pass and take care of all aspects of serialization.
The pros are – won't affect any other Ogre users, the custom developer responsible for it and can't hurt anyone else.
The cons are – demand massive changes to the core of material system, the sub class pass code won't be useful for other users.
...
I like this option, it is much more OO, moreover – the current pass class properties are based on the fixed pipeline, I think that something like a new "empty from properties" pass should be created, from it – a "fixed pipeline pass" and a "shader pass". This way the classes will be much more clear, also ogre code will have much less if\switch statement because of the mixture today. We will also enable inheriting new specific classes like a "Normal map pass" and such, with internal logic if needed and such. This architecture will be much more flexible and pluggable. I don't think this is such a major change.
0 x
Watch out for my OGRE related tweets here.

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Tue Sep 08, 2009 11:29 am

Did you think about just providing your own material script files (e.g. "*.rtsm") which uses its own dedicated syntax and allows you all the flexibility you want and won´t confuse any (especially newbie) user when starting with material scripts? A clean cut between both approaches...
This is clean approach but I loose the whole mechnism of material parsing, and will have to do double work in order to support future evolving of core material parsing. Maybe callback funtion during the parsing might be some sort of solution - but it will be hard to maintain and will force creating some ugly mechnism in order to deal with the context of the call ....

Regarding haffax suggestion - well you said it yourself..
But....
This is really hard to do for the general case. I see this feature growing and outgrowing this simple solution.
Anyway thank you guys - I'll keep update...
0 x

User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
Contact:

Re: Extending the material attribute set

Post by volca » Tue Sep 08, 2009 1:40 pm

How about providing a metadata support for the material constructs? I mean - the material script parser could keep all the comments in the file that have some specific structure (three slashes like doxygen for example). Material/TextureUnit/Pass and such classes would gain const String& getMetadata(). Parsing would be up to the user of the metadata.
0 x
Image

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Re: Extending the material attribute set

Post by Assaf Raman » Tue Sep 08, 2009 1:46 pm

metadata is Nir's option 2 - I think it is a way to go around inheritance, it is a sort of a "text void * pointer". What is the down side you see in my proposal except the work needed to make the change and backward compatibility?
0 x
Watch out for my OGRE related tweets here.

User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
Contact:

Re: Extending the material attribute set

Post by volca » Tue Sep 08, 2009 1:55 pm

I think it is a good idea, actually. The metadata approach is orthogonal to this though - it may provide a way of user specified data for any type of problem, not only directly rendering related. Using comments for that purpose seems better to me than custom attribute - it provides a clean cut between ogre related data and user targetted ones (this was the purpose of my comment). The downside is the need to have a custom parser for that.
0 x
Image

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Re: Extending the material attribute set

Post by CABAListic » Tue Sep 08, 2009 2:14 pm

I disagree. Comments should be comments and nothing else. Giving comments a programmatical meaning stops them from being comments...
0 x

User avatar
volca
Gnome
Posts: 393
Joined: Thu Dec 08, 2005 9:57 pm
Contact:

Re: Extending the material attribute set

Post by volca » Tue Sep 08, 2009 2:38 pm

I understand your point of view - it can certainly be viewed as a dirty approach.
0 x
Image

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Tue Sep 08, 2009 3:43 pm

We may consider another solution in which a Pass will hold set of custom attributes in addition to the existing ones, each of them will be represented as different class.
When a custom attribute will be encountered during the parsing process, the parser will seek for appropriate attribute factory that will parse the rest of the line and create instance of the matching attribute.
For example – when the parser will see a line like
custom_attribute normal_map Normal.dds 1
It will try to create a custom attribute of type "normal_map" and fill it with the appropriate values. Afterwards anyone who would like to query this pass could iterate thru the custom attributes, and find out about different values of them by down casting based on their type.
0 x

User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
Contact:

Re: Extending the material attribute set

Post by Praetor » Tue Sep 08, 2009 3:55 pm

You have complete ability to override and extend any of the parsing. This includes adding new script types (.rtsm) that use the existing parsing pipeline or extending the properties supported by an already handled object type (like pass). Depending on your choice I can give you more concrete examples about how to do what you want.

To get started there's this article tucked away on the wiki: http://www.ogre3d.org/wiki/index.php/Ex ... tCompilers

The first part about the listener interface needs to be updated with details that recently changed in HEAD, but the second section about custom translators is what you want to look at.
0 x
Game Development, Engine Development, Porting
http://www.darkwindmedia.com

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Sep 09, 2009 8:13 am

You have complete ability to override and extend any of the parsing. This includes adding new script types (.rtsm) that use the existing parsing pipeline or extending the properties supported by an already handled object type (like pass). Depending on your choice I can give you more concrete examples about how to do what you want.
This mechanism looks good for extending properties of any script - good to know that.
However I still got two problems with that:
1. I need access to that custom information after the parsing process. For current core objects you simply call some method and retrieve whatever you want.
I.E- you call Pass::getAmbient() in order to get the ambient colour of it. In my case I will have to store the custom attribute data in some other place holder class and access it via some kind of a map where the pass is the key. Other solution might be extending some sort of user data storage method- like Pass::setUserAny() which I already did - to get an identified key in addition to the data itself. That means that the pass will have to hold some sort of map inside it but it is better than holding huge map for all passes.
In D3D9 SDK they have this IDirect3DResource9 interface which use as base class for all other resources like textures, vertex buffer etc that have a method that allows users to add their own private data to a specified instance of it.
http://msdn.microsoft.com/en-us/library ... S.85).aspx
It may be useful to add some kind of method to all material related classes..
2. The separation between parsing and actual member of the Pass methods/attributes will limit me if I'd like to make changes during the runtime for a given pass. Let's say I’d like to turn off the per pixel lighting attribute – I'll have to go to my custom storage class change the attribute that associated with this Pass and re-create the shaders.
The bottom line here is that if I'll use only the translator mechanism I'll have to create some separate mapping database from a Material/Technique/Pass to my custom attributes.
I agree that adding additional methods just for the RT Shader System purpose is not a good solution – so adding some sort of advanced user data association method will certainly do the job here. What do you think?
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Sep 16, 2009 3:53 pm

I just finished the first draft of the material script extension related to the RT Shader System.
I used the current mechanism of ScriptTranslator suggested by Praetor and it work perfectly well !!!
In addition – I didn’t changed anything to the other Ogre core class like I thought I had to do – so things kept clean. Instead I simply used the RT Shader System API during the script parsing to create the relevant render state of a certain pass which will eventually cause generating a shader.
So taking this simple material

Code: Select all

material "2 - Default"
{
	technique
	{
		pass
		{

			texture_unit
			{
				texture MtlPlat2.jpg
			}
			
			specular 1.0 1.0 1.0 32
			
		}
	}
}
And adding these few lines to create this material

Code: Select all

material "2 - Default"
{
	technique
	{
		pass
		{

			texture_unit
			{
				texture MtlPlat2.jpg
			}
			
			specular 1.0 1.0 1.0 32
			
			rtshader_system
			{	
				light_model per_pixel
				integrated_pssm4 5.0 131.0 641.0 5000.0
			}
		}
	}
}
will end up with creating new technique based on this one which its first pass will use per pixel light model as well as integrated pssm shadow handling. The new technique scheme name is default to the shader generator default scheme if no name specified for the rtshader_system chunk.
As soon as I'll finish implementing the normal map extension as part of the core system and maybe some linear depth rendering I'll post it in a new patch.
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Extending the material attribute set

Post by sinbad » Wed Sep 16, 2009 4:49 pm

I think this is the right way to go since is non-intrusive (in terms of code, since I hope the new attributes are handled entirely in the RTShader component with no changes to the core), contextual and orthogonal to the original material definition.
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Sep 16, 2009 5:12 pm

I think this is the right way to go since is non-intrusive (in terms of code, since I hope the new attributes are handled entirely in the RTShader component with no changes to the core), contextual and orthogonal to the original material definition.
Yes - that's the way I did it - the RTShaderSystem component register a translator and handles all attributes within the rtshader_system via common interface of the SubRenderStateFactory. That way a custom shader based extension that users will add to the core feature set will have the option to create and handle their custom attribute set. All core objects of the RTShader System will provide parsing code as well... Anyways Ogre core remains clean :)
0 x

User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
Contact:

Re: Extending the material attribute set

Post by Praetor » Wed Sep 16, 2009 6:41 pm

This is really great. I think the solution you came up with the is the best, and I really like the results from the entire system. Really good work.
0 x
Game Development, Engine Development, Porting
http://www.darkwindmedia.com

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Tue Oct 06, 2009 2:59 pm

OK -

Now that I've done with material parsing part, the RT Shader System can read and generate shaders based on custom material properties.
But.... I have to implement the opposite thing as well - meaning extend the export code to in order to enable my artist adding these custom attributes.
Currently I use LEXI Export as my main exporter which in turn utilizes the MaterialSerializer to do the actual material serialization.
I wonder what is the best way to add these custom attributes of the RT Shader System to the exported material.
I guess some sort of callback mechanism from the MaterialSerializer will do the job... but currently this option doesn't exist.
Sub Classing the MaterialSerializer is also an option but I have to virtualize all it writeXXX methods first.
The worst option is to write my own custom serializer.... that would be just a nasty Copy Paste + my few lines of code...
I'd like to hear what do you guys think...

Nir
0 x

User avatar
Assaf Raman
OGRE Team Member
OGRE Team Member
Posts: 3092
Joined: Tue Apr 11, 2006 3:58 pm
Location: TLV, Israel

Re: Extending the material attribute set

Post by Assaf Raman » Tue Oct 06, 2009 3:16 pm

I vote for "callback mechanism".
This way other components could "hook" to the same callback and add other extensions to the material without having a complex inheritance.
If you sub-class – from who the next one should inherit – from your new class or the original class, and what about the third programmer that want to use the 2 first extensions and so on.
0 x
Watch out for my OGRE related tweets here.

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Extending the material attribute set

Post by sinbad » Tue Oct 06, 2009 6:06 pm

Yes, I think some kind of hook in the MaterialSerializer to allow external systems to inject their own properties during export is a good idea.
0 x

User avatar
Azgur
Goblin
Posts: 264
Joined: Thu Aug 21, 2008 4:48 pm

Re: Extending the material attribute set

Post by Azgur » Wed Oct 07, 2009 7:32 am

This thread makes me happy :)
These extensions and the RTShader system will really ease the process of setting up an art pipeline.
I can't wait to put it in practice :D
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Oct 07, 2009 9:11 am

This thread makes me happy
Glad to hear that - my artist is also happy... :D

Anyways, I'll go for some sort of MaterialSerializer::Listener inteface - you'll have to sub-class and override the relavant methods.
The methods I thought about are in the manner of notifyXXXWriteBegin and notifyXXXWriteEnd -
So you'll probably have
- notifyMaterialWriteBegin(MaterialSerializer* serializer, const Material* mat)
- notifyMaterialWriteEnd(MaterialSerializer* serializer, const Material* mat)
- notifyTechniquelWriteBegin(MaterialSerializer* serializer, const Technique* tech)
- notifyTechniqueWriteEnd(MaterialSerializer* serializer, const Technique* tech)

and same goes for Pass, GPU programs and Texture units..
Is that make sense :?:
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Oct 07, 2009 11:00 am

Just another thing -

The classes that will derive from MaterialSerializer::Listener will have to access some of the private methods of MaterialSerializer such as writeAttribute, writeValue etc.
The first option is to make them public just for that purpose.
The second is to declare MaterialSerializer::Listener as friend of MaterialSerializer, add mediator methods that will call the Serializer methods and the sub-classes of it will use them.
0 x

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19261
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
Contact:

Re: Extending the material attribute set

Post by sinbad » Wed Oct 07, 2009 4:34 pm

Another option to having separate methods is just a notifyWriteBegin() and notifyWriteEnd() with an enum identifying the element being encountered, which can just keep the number of separate methods down a bit (which if you have fireBlahWriteBegin() etc methods too can make quite a difference). It does mean a switch() in the receiver but these are very cheap. It's also a bit easier to extend later.

I'd allow the write() methods to be public, that's nicer than friend declarations which don't get inherited on all compilers anyway.
0 x

User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
Contact:

Re: Extending the material attribute set

Post by Nir Hasson » Wed Oct 07, 2009 6:00 pm

The reason I want separate methods for material, technique pass etc is that I need to access the specific instance that is being written.
I.E - when a certain technique is about to be written I want to access its properties and know what extra things to add or maybe skip the write process..
Anyways - I minimized it to xxxlEventRaised(Serializer, SerializerEvent, Skip, xxx Pointer) - where SerializerEvent enum defines specific serialization events - pre write, write begin, write end etc ...
That is actually a merge between both solutions.

Regarding the write() methods - I'll take your advise..
0 x

Post Reply