Question regarding Nanite and Material Draw Calls

hi, now that nanite handles all mesh draw calls for us, i’m a little confused about what that leaves for material draw calls.
for example, lets say i have a scene with 200 unique meshes, and all of these 200 unique meshes use the same master material, but each have different parameters changed in their own material instance. (for example, each one uses its own unique texture and tint parameters)
so, 200 meshes, 200 material instances, 1 master material
how many material draw calls would that make?
do material instances count as draw calls with nanite?

sorry if this is oblivious, im quite new.

Material instancing has virtually no impact on performance. It’s a workflow optimization.

The documentation makes it sound like there is 1 draw call per material (or instance) in the scene.

I tested generating 3000~ MIDs generated in Blueprint and it was taking upwards of 4-7ms to draw them on a 3900x.

Basically you’ll have fewer draw calls than if you were using non-nanite meshes, but high material counts are still slow.

2 Likes

Thanks, so multiple material instances of a master material don’t count as 1 draw call, right?
I began thinking about this after seeng the project file of the Valley of the Ancients tech demo. Basically every mesh there had unique textures and each were instances lots of times. Seems doable, as long as kept in check.

10 different material instances is 10 draw calls even if they all share the same parent material. (according to my testing, and assuming I am reading the documentation correctly)

Material instancing doesn’t matter for performance (even on non-nanite meshes). It exists to make working with materials easier, not to make them run faster.

2 Likes

As other people said, instancing a material does not have any impact on performance. If you have an instanced and non-instanced material, they would cost the same at run time.

What it sounds like you want to do is write a single material that allows inputs for unique textures for some objects in the scene. For example, if you want to have 30 different stone pillars, but you want them to each be a different color, you could use one material and an id mask and then assign the different colors to each pillar. The same is true of any texture you want to be unique. That way, they’d all be different colors, but only use one material.

2 Likes

I see, thank you!

Yes, that’s exactly what I want to do. I have a modular kit that all shares the same properties but I want to create unique textures for each piece. I’ll be creating a master material with the texture set as a parameter so that I can swap it for each piece. Though I hoped maybe all instances would count as 1 draw call so that I’d have amazing performance, hahah. Anyways, I’ll figure it out.
Thank you!

Two quick things:

  1. If all you’re doing is making small changes, decals may be a better way to go. For example, I want graffiti on a wall. Rather than having each wall with graffiti get a unique material, it’s much better to just make a decal for each piece. This also lets me move it around and adjust it separately from the wall.

  2. If you want a couple of similar changes to be made in different shapes, you can use vertex painting. For example, if you want cracks on your pillars, you could just paint the cracks in wherever you want them. This way, the cracks will have the same properties on each pillar, but will be in different shapes.

1 Like

Thanks for the tips, i do plan to use both decals and vertex painting for extra variation but the main visual goals i have seem to be only achiavable through a unique texture on each asset.

The best way to slove material instances customization problem with draw calls is to use custom primitive data. For example if you want to change color of the assets in the scene without new material instances, all you need to do is to make proper material with vector3 node reference to custom data, then one material instance and change color by custom primitive data property. The color data is saved as meta data directly in the object not in the material instance so you don’t need to make 200 material instances for 200 actors.

1 Like

yeah that sounds good, but i do need to use different textures for each material instance. afaik there is no way to use custom primitive data for textures?

You can make texture atlas (only one drawcall) and by custom primitive data select proper texture from it - using flipbook node or simple adding to texture coordinates.

1 Like

oh that makes a lot of sense. great idea, thank you! i will implement something like this to test performance gains.
cheers!

Cheers and good luck!

1 Like

You can use Custom Primitive data, this will create only one draw call for multiple assets using the same textures but with different colors. This works well for TexCoords using Trimsheet textures too.

1 Like