Advertisement

How can a mesh in blender have multiple materials while game engines can have only one?

Started by February 26, 2021 01:08 PM
4 comments, last by swiftcoder 3 years, 8 months ago

I was learning game engine programming in the past and one thing I've learned was that when you render a mesh, that mesh can only have one material assigned to it because of the way that a draw call needs to be defined programmatically.

So what is the catch here? In Blender (in edit mode) you can assign multiple materials for the same mesh (let's say 6 different materials for each face of a cube). If you do that and export your cube in FBX format how will a game engine (let's say Unity) knows how to render the cube? Does Blender convert all the materials into a single one (I believe this can not be done due to the fact that the properties of a material can not be merged to describe multiple materials)?

Or maybe the game engine will actually consider each face of the cube as a separate mesh, meaning that the cube will need 6 draw calls to be rendered?

Thanks.


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

I'm not sure how DCC applications like Blender implement their rendering backends, but these applications are made with different concerns in mind. The usual use case is you make a few models with however many materials you want and you export them for external consumption, but that's about all they're meant for. Creating models, texturing them and animating them.

Game engines on the other hand, as you might already know, have many more systems and they all have to run together in real time. Couple that with the hundreds of models a game scene usually contains and you can start to see a game engine's appeal for optimizing their rendering as much as possible. I think for this reason certain game engines only let you apply a few (or even one) material to a model at any one time. Keep in mind that you can have a material with a custom shader that accepts as many textures as the graphics subsystem will let you bind, but the optimal practice when exporting from a DCC is to do some sort of texture unwrapping to make one texture out of all your blender/maya/whatever materials and textures.

As far as I'm concerned, Unity let's you set multiple materials under a single MeshRenderer component. Whenever you import an FBX you'll see all the materials listed for that model with the option to extract the materials, which just creates new materials based on the material specs in the FBX file. I'm not sure how Unity implements their render queues, but it's entirely possible that they bake all the extracted materials into one. It could also be that they implement render queue sorting differently for optimizations sake.

Advertisement

babaliaris said:
Or maybe the game engine will actually consider each face of the cube as a separate mesh, meaning that the cube will need 6 draw calls to be rendered?

I guess that's the norm. A better example is UV seams, because there is no option to ‘bake multiple UVs into a single one’.

So if you model a cube and texture it, the modeling app likely stores two meshes internally: One with 6 vertices for geometry, a second with maybe 14 vertices for the UV map (the vertices store 2D UV coords, not 3D positions, but otherwise the same data structures can be used for both, with a mapping between them.)

Then, when exporting, the app likely duplicates vertices and edges at uv (or other) seams. So the final model to render has 14 UV+3D vertices.
The same may happen due to hard edges (no shared normal on vertices), different materials for different faces, different set of skinning bones, etc.

I was learning game engine programming in the past and one thing I've learned was that when you render a mesh, that mesh can only have one material assigned to it because of the way that a draw call needs to be defined programmatically.

It does not have to be so. Since GPUs became very flexible, we can do what we want. We can blend layers of materials at runtime if we want (doing correct PBS for such is a very active research topic). We can also try to merge all layers down to one standard set of PBR textures and avoid runtime mixing. Unity surely supports both.

Thank you for your answers! I tried it and it turns out that Unity actually creates one mesh object with multiple materials assigned to it. Now I don't really know how many draw calls it will take to draw the cube, I'm still learning how to use Unity's renderer profiler…


void life()
{
  while (!succeed())
    try_again();

  die_happily();
}

 

Typically there will be a conceptual “mesh”, that is actually comprised of multiple “SubMeshes”. When you export a cube with a different material on each face, Unity will import that as a Mesh with one SubMesh for each face, and each SubMesh will only have a single material.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement