Sign in to follow this  
Raeldor

Materials... Model Instance, Model Resource or Both?

Recommended Posts

Raeldor    254
Hi All, At the moment I have the materials for a model as part of the model resource class. The model resource class (containing vertex and index information and such like) is shared by all instances of the same model and this data is loaded from the model file. I came across an instance today though, where I need to change the material on a per model basis. This is for object picking and highlighting using the mouse for which I need to change the shader to modulate2x (the shader is currently part of the material, which still seems to make sense). I guess the question is, when a new model instance is created, should it copy the material information to the instance from the resource and use this copy, or should I just have some kind of shader override at the model instance level? The shader override doesn't seem to make as much sense at the model level though, as the shader being tied to the material seems like a good design. I assume highlighting models like this is quite common, so I am curious to hear how other people have handled it in their engines. Thanks! Rael

Share this post


Link to post
Share on other sites
CRACK123    235
Hi,

In my code the shaders is tied to the materials and then vertex and other information is batched per materials. I find that it makes more sense to tie the shader to material as then it allows me to use one shader for a lot of things rather than changing shaders every time.

Hope this helps.

Share this post


Link to post
Share on other sites
Raeldor    254
Quote:
Original post by CRACK123
Hi,

In my code the shaders is tied to the materials and then vertex and other information is batched per materials. I find that it makes more sense to tie the shader to material as then it allows me to use one shader for a lot of things rather than changing shaders every time.

Hope this helps.

But is the vertex and material information shared between similar models? Ie, do all tree models share the same vertex buffer and material information

The other thought I had was to have some kind of 'override shader' on the model which would override the shaders in any of the materials. Does this seem like a bit of a kludge, or is it justified for things like highlighting?

Thanks!

Share this post


Link to post
Share on other sites
Bob Janova    769
I would treat materials in a similar way to textures: a material isn't tied to a particular model, you instead have a collection of loaded materials which are used by each model.

Share this post


Link to post
Share on other sites
Raeldor    254
Quote:
Original post by Bob Janova
I would treat materials in a similar way to textures: a material isn't tied to a particular model, you instead have a collection of loaded materials which are used by each model.

I see, but that material information is present in the model resource file (ambient, diffuse, texture maps etc.) so is loaded and created as part of the resource which is used by each model instance. When model instances are created, should each instance then hold it's own material pointers?

Share this post


Link to post
Share on other sites
Bob Janova    769
Hmm, in that case I don't think your model and mine are very compatible, so you might just want to scratch my advice. I was imagining a situation where you have a material 'Aluminium' or whatever (which defines the texture, lighting model information, maybe friction coefficients and stuff too), as a global resource. The model would then say 'triangles 0-45 are using material Aluminium'. That would seem to me to be wasting less space if you have lots of objects using a few materials.

However I don't mean to restructure your whole app so you can just ignore me =).

Share this post


Link to post
Share on other sites
bzroom    647
The way mine is setup is all the resources get managed at the top most layer. This includes "models, materials, surfaces, shaders, passes, and lights"

The models are basically sub lists of geometry with reference counting so that it dosn't get deleted until the last one deletes it. If it is skeletal geometry it sets a flag that says it requires a duplicate copy that can not be instanced. (software vertex blending)

The materials are pointers to a shader, and the required surfaces (textures), and parameters. These are again protected by the same unique requirement flag.

The model and the material group alike have a "spawn" feature which is what gets called new a new model or material wishes to instance it and decides wether a new copy is needed.

The following init code:

p1 = r->CreateModel("player.ms3d", pos1);
p2 = r->CreateModel("player.ms3d", pos2);
p3 = r->CreateModel("player.ms3d", pos3);
r->SetNewMaterial(p2, "redshirt.mat");

Results in: //created by

Geometry Copys: 4 //each model points to the base, and each has a unique copy
Models: 3 //p1, p2 , p3
Materials: 2 //p1, p2
Surfaces: 2 //p1, p2
Shaders: 1 //p1


I don't know if that helped at all but I typed alot before I had doubts so make of it what you will.

Share this post


Link to post
Share on other sites
jkleinecke    251
In my engine we call our collection of vertex buffers/normals/etc... a mesh. And we consider the model to be the mesh+materials. That way we can create a new model instance, re-use the old mesh and attach a different set of materials to it.

Share this post


Link to post
Share on other sites
Raeldor    254
Quote:
Original post by jkleinecke
In my engine we call our collection of vertex buffers/normals/etc... a mesh. And we consider the model to be the mesh+materials. That way we can create a new model instance, re-use the old mesh and attach a different set of materials to it.

But doesn't the model file format contain information about the materials and textures?

Share this post


Link to post
Share on other sites
bzroom    647
Yes, thats why in my system (which sounds like jkleinecke's), I let the renderer class load the model not the model class. That way when its reading the file and it comes acrost a "grass.bmp", it looks up a "/materials/grass.bmp.mat" which defines which shader and other paremeters to use. So in the model editor the only reason to apply the texture is to set coordinates and the filename in the mesh. The grass.bmp.mat could load up 3 totally different maps if wanted.

I have been thinking about moving the model loading code into the model and then passing in a material request function that it can call.. but I'm trying to avoid everything knowing about everything, I'd rather just the renderer knew about everything.

Share this post


Link to post
Share on other sites
Bob Janova    769
Quote:
Original post by Raeldor
But doesn't the model file format contain information about the materials and textures?


A model file has to have a reference to materials and/or textures (typically a filename), but the actual resources shouldn't be included in the model file.

Share this post


Link to post
Share on other sites
Raeldor    254
Quote:
Original post by Bob Janova
Quote:
Original post by Raeldor
But doesn't the model file format contain information about the materials and textures?


A model file has to have a reference to materials and/or textures (typically a filename), but the actual resources shouldn't be included in the model file.

Aha, here lies my problem i think. So the materials (diffuse, specular, maps etc.) should be held in a seperate file?

Share this post


Link to post
Share on other sites
bzroom    647
What format are you using? I've never heard of a format including all the map data inside itself. Unless exept maybe a proprietary game package.

Share this post


Link to post
Share on other sites
Promit    13246
So on the one hand, you have the geometric information that constitutes the model. On the other hand, you have the material which specifies the shaders in use. These two classes are not related.

What's missing in the middle is that shader constants can be sourced from multiple places. So you want to be able to source shader constants from the material, but you want to be able to store them in the model file too. (Note that textures are also shader constants.) You may also want to be able to override certain settings at runtime.

But to get back to your problem, the mistake you made is introducing an artificial dependency between geometric information and the shaders used to get it on screen. When you go to render, you should render X model with Y material. Forcing a model to use a certain shader is just asking for trouble, as you've discovered.

Share this post


Link to post
Share on other sites
Raeldor    254
Quote:
Original post by honayboyz
What format are you using? I've never heard of a format including all the map data inside itself. Unless exept maybe a proprietary game package.

It's my own format. It includes all the vertex information + material diffuse, specular and ambient and the texture maps. I guess I need to create a new file format to hold the latter and reference that?

Share this post


Link to post
Share on other sites
bzroom    647
Quote:
Original post by Raeldor
It's my own format. It includes all the vertex information + material diffuse, specular and ambient and the texture maps. I guess I need to create a new file format to hold the latter and reference that?


Thats what I suggest. In the occasional instance that more then one object use the same map, your method would have those map's stored multiple times. Modification to the shared map would require updating all the model files.

If the maps are seperate then any number of models can reference that map without taking up more storage space. And if the map needs adjusted it will propigate to all the other models. (Though you have to make sure this is really what you want to happen.)

What program are you exporting your format from? Is it your own editor?

Share this post


Link to post
Share on other sites
Raeldor    254
The maps themselves are quite small since they only represent the diffuse, specular and ambient colors plus the names of the texture maps. The textures themselves are shared via the resource manager.

I am exporting from 3D Studio Max. I wrote an export script for my model format.

So, it still leaves the question that if the reference to the material name is in the model file and that's loaded into a resource class by the resource manager along with the vertex information etc., when an instance of the model is created, I guess the model instance should then has it's own copy of the pointer to the material so that it can be changed on a per model basis?

Thanks

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
You can also consider drawing your object twice to get the effect that you're looking for. On the first pass you would draw the original model, with its attached material. Then, turn on blending and render the model a second time with the a simple shader used for highlighting, or any other indicator. This idea seems like it might require less work than some of the other suggestions. Of course, in the long run it's probably best to keep materials separate from the models, and just point to them.

This multi-pass technique is good because you don't have to change any shader parameters, which might have led you to copy the orginal material. It also alows for other effects to be added in the future.

If your second shader is simple, then it should also be fast. The hit for drawing the model will be minimal, (depending on complexity) as you're only drawing a single object twice.

Share this post


Link to post
Share on other sites
bzroom    647
Quote:
Original post by Raeldor
...I guess the model instance should then has it's own copy of the pointer to the material so that it can be changed on a per model basis?



Yes.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this