🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Designing material system for game engine

Started by
1 comment, last by Shaarigan 4 years, 7 months ago

Hi everyone!

I started to learn DirectX and decide to make simple DX game engine. My intention was to make material system as data-driven as possible, so that I can add and modify materials without defining classes and structures in C++ and recompiling it after smallest change. At the moment I have this implementation - Shader class, that compiles shader, loads reflection info for constant buffers and samplers and creates DirectX constant buffer, and Material class that has reference to it's shader and just store material parameters as data blob, which is then copied to shader's constant buffer on render.

For now all of my scene creation is hard-coded, so my next step was to move scene config to some json file. The problem is that I want to sort my meshes by material, but don't know how to generate material ID for them. For now I have 2 variants:

1) static - all materials are stored in material library, and shared between all meshes. Mesh just store material index in this array, and it's used as material ID when sorting. The problem with this approach is that it will be difficult to change some parameters in material if I want to animate something, as I'll need to create new instance of material, save old material id, then somehow restore it when animation is done. If I have 10 animated materials with same parameters, they will be treated as 10 different materials on render.

2) dynamic - every mesh has copy of material with all it's state. On load I calculate hash from all shader params, textures, blend state etc. Then I just use this hash as material ID. The advantage is that materials with same parameters will always have same material ID, no matter if they are created from code or from scene file. The disadvantage is run-time and memory costs, but memory can be optimized if implement some sort of lazy copying only if some of parameters is changed.

I tried to google some articles on this topic but haven't found anything useful. It's look like Unity uses some sort of first variant, but I can't be 100% sure.

Thanks in advance!

Advertisement

It is not just Unity, I'm 99% sure that Unreal uses the same because if you have one Material on multiple objects in your scene then you have always the same animation state of those objects. So I feel to claim that it is pretty standard to have different materials even if they share the same shader to solve different problems.

In the end, it is the shader that makes a material, not its parameters so have multiple material instances inherit from the same shader feels fine for me as long as all of them have the different settings.

But I know that you can also add a material to a shader in Unity that is a new instance even if the material has been used before. So instead of sharing materials, Unity shares material references. However, this seems to be possible in code only as you have two different properties

public Material material { get; set }
public Material sharedMaterial { get; set; }

while the shared variant just assigns the class pointer, the non-shared one instantiates a new one and copies the old values to it.

My two cents to the topic are that I don't see any reason you should create dynamic materials instead of having a cache in your engine that knows all material instances and offers those to the render objects. Most of the time the work is done by the shader, for example a shader coloring objects based on their vertices or outline shaders or whatever. If you want to animate an object, for example a conveyor belt, you want to animate all of the instances the same way to save performance if there is a factory with hundrets of conveyor belts or else they are controlled by code anyways so code passes the shader states and not the material

This topic is closed to new replies.

Advertisement