Menu Close

3dsMax tips #3 How to make imported tree animation 15 times faster

UPDATE! Fully multi-threaded explicit normal calculation has been implemented in 3dsMax 2022.1. Now, the explicit normal version of model is deforming at 2.8fps( was 0.6 fps). That’s almost 450% improvement. BUT, please remember still the best way to make the deformation faster is not having 11 million extra normals. converting explicit normal as smoothing group will give you 17fps.

The models I have been dealing with in 3dsMax have been mostly internally made or purchased as .max file, which means I usually do not have explicit normals on my model. If you make a model in 3dsMax, you usually smoothing group instead of explicit normal.

But, most other DCCs are using explicit normal. Which means when you import fbx, obj or alembic. You will be likely to have a lot of explicit normals. I mean a lot. All this explicit normal also need to be recalculated when your object is deforming, which means it can have a great impact on your animation playback performance.

Recently I have learned the impact of normal calculation is HUGE. I mean really HUGE. Another reason why this issue surfaces more recently is that 3dsMax dev have beenputting a lot of effort to preverve explicit normal in various modifier. In the past, many modifiers had destroyed on the stack, now more explicit normals have preserved and causing slow down.

I downloaded a MaxTree sample file from https://maxtree.org/products/plant-models-vol-16/ 
They have the original max file and fbx file.Perfect.

I chose the biggest one, MT_PM_Albizia_saman_01_01_H, and applied animated Bend modifier.It has 4,4mil verts and 3.8mil tris. This is what it looks like in my Ryzen 2700X(kinda old… I know). I turned off real time playback.

The native max mesh from .max file plays at around 14fps. Not bad for 4.4 million verts animation.
Now I imported the fbx version of same tree. I got 0.6fps.
In other wards, max mesh took less than 2 second to play 24 frames. fbx mesh took 36 second to play 24 frames. That’s almost 20 times slower! When I check the amount of explicit normal, there were 11.399 million normals! File size also jumped from 294M to 645M! This mesh has total 11,399,301 normals. 11 million! Essentially you mesh becomes almost 16 million verts instead of 4.4 million.

3dsMax native mesh
Mesh from fbx with explicit normal

 

 

 

 

 

 

 

 

 

 

 

How to solve this issue

First of all, this is why it is always better if you stay in 3dsMax all the time. The native data is always the best. But, if you have to get data from outside of 3dsMax. The ultimate fix issue would be converting to smoothing group and remove all explicit normals. Unfortunately, I have not found a good way to do this for 4.4 million verts model.

So, I took a little bit of time to find a solution, and here is two work arounds.

Apply Mesh Select for Editable Poly, Smooth for Editable Mesh and set to “Off in render”

Some may think “why not Edit Normal modifier?” because it turns out that Edit Normals can not completely remove normal interface.  So far the only way to completely wipe out explicit normal is applying Mesh Select modifier on Editable Poly or Smooth modifier on Editable MeshThen, by setting this to Off in render, you wipe out explicit normals only for viewport and get correct smoothing while rendering.

So, by doing this, I got around 9fps. That’s a lot better than 0.6fps. That’s 15 times faster.

Do not turn on Auto Smooth on 4.4 million verts model. You don’t need to smooth anything. Just applying Smooth modifier on Editable Mesh will wipe out all normals. Same for Mesh Select, just apply it and change to “Off in Render”.

Conclusion

  • Use always the native mesh if you can. The native mesh is always the best.
  • Use always Smoothing group instead of explicit normal if you can.
  • “Smooth” to wipe out explicit normal in Editable Mesh.
    “Mesh Select” to wipe out explicit normal in Editable Poly.
    Edit Normals modifier can not do this.
  • After the model is imported, always try this if the model has animation.
  • As you can read the below paragraph, having any explicit normal will make 3dsMax calculate something all the time. Even tho you have an explicit normal per vetex(Usually it is a lot more), it is essentially same as having one more mesh. in the above case, it had 11.4 million explicit normals, which means it is same as having 4 trees than 1 tree.  On top of that, this would happen for each modifier after animated modifier. So, this tip will be always valid i n the future.
  • Don’t just assume 3dsMax would be slow for deforming hires mesh. If you for really low fps, always try something. It would be always case by case But, generally speaking, 3dsMax should not havce problem playing more than miilion verts around 10fps.

Technical details

One of the main 3dsMax developer, Peter Watje, game some insight about this issue. I’m sharing the full text. It is must read for any 3dsMax users who want to know the technical details. Thanks, Peter!

Mesh Normal Interface is really the correct name but basically it is an object that is attached to the mesh when you want to override the smoothing groups. It lets you describe normals by smoothing group, or by which faces they are attached to or by the user explicitly setting the value changing the normal direction. It carries around a lot of data even if you don’t have any explicit normals. So for instance if you Box and you put an Edit Normals all the normals start out as Unspecified Normals and are colored blue which means the normals are generated by smoothing groups. Then there are Specified Normals in which case the normal is still computed but the faces that are used are determined by the user. For instance if you Unify some normals they become a Specified Normals(cyan) and the normal is computed by all the faces the original normals where attached to, Finally there are Explicit Normals(green) which the changes the direction of the normal and that normal is no longer computed in anyway. All that data needs to be stored in the Mesh Normal Interface.

Reset Normals sets all the normals back to Unspecified. The Mesh Normal Interface is still there it just uses the smoothing groups to compute the normals but there is still alot of data there.

When it comes to performance it breaks down to were the normals are computed and how much data is copied to create them. With no Mesh Normal Interface the normals are created when the mesh is displayed and is actually done by a shader that takes the mesh and the smoothing groups and generates the normals directly on the display mesh. It is really fast which is why in some cases when you put certain modifiers on the stack that strip out the Mesh Normal Interface it becomes faster.

The other way performance path is thru the Mesh Normal Interface. Since it is data on an object that flows up the stack that means it may need to be copied which is a heavy weight operation. It also means that any geometry changing modifiers need to also deform the explicit normals in addition to the vertices. So when you come to the display all Specified and Unspecified Normals need to be computed if they were not already and merged with the Explicit Normals and then attached to the display geometry. So you performance is determined mainly by how heavy weight your stack was. Previously the stack was super conservative dealing with normal. It did extra copies and the deforming of normals on a single thread. We are looking at making it less conservative to get better performance but that might bring up other unforeseen issues.

A Tip in a tip

How to set modifier to work only in viewport? Right click menu of the modifier. You can set a modifier to on/off or on/off only in render or viewport.

How about making your workflow 15 times faster? Meet renderStacks!