Material Draw calls reducer

Hello! Sometimes you creating box with 2 materials, but draw calls is 6 not 2. Or when you load static model with only 2 materials, but draw calls is 500 not 2.
Because triangles are not sorted by materials in geometry.groups.
After load buffered model, you should just use code: mat_draw_calls(mesh);
For indexed geometry:
mesh.geometry=mesh.geometry.toNonIndexed();
mat_draw_calls(mesh);
Download: GitHub - chasergit/mat_draw_calls
There is also simple code to merge buffer geometry.
image

2 Likes

Sounds very useful, well done!

1 Like

There is a major flaw in how 3JS calculates draw calls that under certain circumstances, wrong value is returned.

Take a geometry with 10,000 faces, 16,000 vertices and two materials.

I can generate a mesh with 2 draw calls or 10,000 draw calls, reported.

Guess what? FPS stays at 60 for both without any hiccups.
Why? because the number of draw calls should be the total number of unique materials used.

I’m not sure what you’re trying to say. Yes, you can draw 10,000 triangles with a single draw call, and you can do it with 10,000 draw calls, and yes - you can do both at 60fps provided your hardware is good enough.

1 Like

Some softwares like “3ds max” exports mesh with unsorted triangles-materials and we got over draw calls, thats why i created code to reduce it. And when merging two object is too need to delete repeating materials.

Hey, this is an interesting idea and sorting triangles/merging groups can definitely improve performance in some situations so thank you for sharing your tool. Agreed that Max exports are often badly optimized.
However I think it’s generally better to optimize the model ahead of time rather than operating on a three.js mesh. There are some great tools for doing this.

Have you seen gltfpack?
Also check out the readme of its parent package meshoptimizer which goes into a lot of details about the kind of optimizations that are possible.

Another great tool is gltf-transform. It does less low level optimization (as far as I know) but it’s also much less likely to break the model/mess up the internal hierarchy.

The downside is that you always need to do a visual inspection after processing as these tools can break models (in particular animated models). Oh, and you need to use glTF. But maybe that’s an upside :grin:

5 Likes

I while not using gltf. Only obj and fbx.

That statement couldn’t be any further than truth. What is important that CPU can accomplish all the given tasks in a time period that your monitor refreshes itself. In my test page, using a 6 year old desktop with average specs, Chrome can handle 20000 draw calls per frame requesting material index while maintaining 60 FPS.

The point is, when it comes to draw calls, the time to fulfill these calls is important NOT the number of calls.

I hope I made it easy for you to understand what I’m trying to say.

1 Like

Yes, agreed. It will help, specially mobile devices.
Definitely a useful asset.
Just wanted to let you know these calls on material index are very short, ( about few micro seconds )

I don’t know why 60 fps and 20.000 draw calls in three.js. Maybe good computer or not render loop.
Here 12 fps then set method naive and 10.000
https://threejs.org/examples/webgl_instancing_performance.html

Do you have a demo of chrome running 20k draw calls?

I get around 73 fps

1 Like

Super computer. Unlimited “requestAnimationFrame” to 60 fps.

what language is this?

Screen Shot 2021-08-29 at 12.17.09

1 Like

Russian, apparently.

2 Likes

Ha, the answer is actually quite banal, the requestAnimationFrame is limited to the refresh rate of your screen, which in my case is 144Hz, or 144fps.

There are a number of caveats to that, but this is generally true. Part of the reason why I got a “high refresh rate” screen is to be able to test my work at higher than 60 FPS.

but why? for VR content?

File mat_draw_calls.js translated to english now.

1 Like

not necessarily, I believe higher refresh rate will become the norm slowly. As someone who makes games/apps I want to make sure that the content I create looks/works well on a range of hardware. For example, some animation bug might not be noticeable at 60FPS, but be very obvious at 100+FPS, it’s not common, but I did encounter a few bugs like that in the past.

There are also cases where higher FPS puts more strain on the engine to the point where the device gets quite toasty, being able to see that strain for yourself makes you aware of it and lets you plan for how to deal with it.

1 Like

My client recently: “the app is looking great, it’s running at 240FPS on my machine.”
Me: :exploding_head: :exploding_head: :exploding_head:

Sitting here on my laptop from 2016 like

4 Likes