Menu Close

Category: Demisfying 3dsMax

USD in 3dsMax #2 – USD Stage

Now you have a USD file. How would we consume in 3dsMax? Traditionally, you would just “import” the data from the file, and native 3dsmax data would have been created.We have used .obj, .fbx, .iges, and other CAD formats in this way.

Another way is referencing the file through a “container” object. Instead of generating max native data in the max scene, the data will be generated on-the-fly as it needed. Many renderers’ proxy object and 3dsMax native alembic import uses these methods. Scene Xref is the same concept.

The obvious advantage of this workflow is that It makes your max scene lighter. Since all the data is outside of the max file, the file saving is quick. The scene navigation and evaluation are also faster since everything in the references file is considered as one object in the master file. It is like you attached all the objects as a single object. But, that also means that we would lose control over individual items in the file.

When 3dsMax dev implemented Alembic, they took a hybrid approach. The data is still referenced. But, it was referenced at the object and controller level. This provided a certain advantage over the other 2 methods, But, it also had its own disadvantages.

For USD, 3dsMax dev is providing multiple ways of consuming USD data. You can just “import” like obj or fbx. Or, you can reference it. As of now, the focus has been more on the referencing side.


So, what’s USDStage? According to Pixar, “Stage is the USD abstraction for a scene graph derived from a root USD file, and all of the referenced/layered files it composes. A stage always presents the composed view of the scene description that backs it.” Dang, such an un-artist-friendly explanation. In English, the Stage is the assembled(composed) scene. As I mentioned in the previous post, USD is not just a file format. It is a “Composition Engine”. It provides various ways to build a scene, and the Stage is the result.

If USD for 3dsMax is installed, you can make a new object called “USD Stage” from Create Panel > Geometry > USD > USDtage object and browse a USD file. Or, 3dsMax will make one for you if you can pick a USD file using File > Reference > UDS Stage… menu. We can reference a USD file with this object. Apparently, this is how we are supposed to consume USD. Importing a USD file as DCC native data is considered an old-school way.

This is what it looked like when I loaded the NVIDIA Attic sample as a Stage object. As you can see, there is only one “UsdStage001” object in the scene.

If you pick a USD file to load, this dialog pops up. “Root Layer” is the file we are loading. Why not just call it “File”? Well, that’s because this is the correct USD term. 3dsMax developers decided to stick with USD terms instead of 3dsMax terms for USD. You will notice it again in many places.

When you load an USD file, you can load only a few branches instead of loading everything in the USD file. It is called “Stage Mask”. Stage object currently allow to mask only one tree.

Now we have this foreign data referenced in 3dsMax. We need to display and render this data. But, we don’t necessarily want to convert all these data as max native data. Think about VRayProxy. It is render-ready data for VRay. There is no reason to convert this data as 3dsMax data and convert back to the VRay data. VRay directly loads and renders VRayProxy.

This is also a key concept of consuming USDStage. USD data stays as USD. This certainly affects some of the user experiences while using USD in 3dsMax.

Displaying USD Stage

When USD for 3dsMax displays the objects, it doesn’t create a 3dsMax mesh. It generates Nitrous mesh directly. Under the hood, there is a Hydra delegate for Nitrous. If you are a tyFlow user, this is also how tyFlow works by default. Unless a Mesh operator is added, tyFlow doesn’t make a 3dsMax mesh. It generates Nitrous mesh and sends it directly.

This is certainly helpful for display performance since it is reducing the overall process from 2 conversion(USD > Max data > Nitrous data) to 1 conversion(USD > Nitrous data). But, this also means that you will not get exactly the same viewport features available for 3dsMax objects for USDStage objects. For example, Flat Color or Hidden Line mode wouldn’t work for USD Stage objects.

Viewport Display rollout

But, having its own control for display also means that dev can try something new. This is one of the options in “Viewport Display” rollout in a Stage object. Stage objects provide 3 different display modes.

  • 3dsMax Wire Color mode – uses the color of Stage object for all prims in the Stage object. Since it doesn’t display any materials. It ignores all uv data while building Nitrous mesh. Also, it allows to utilize consolidation 100% since all prims in the USD could be a potential consolidation target. This is the fastest way to play the USD Stage.
  • USD Display Color – uses each prim’s display color attribute. This also ignores all uv data. But, the consolidation will be limited to the same color of objects.
  • USD Preview Surface – shows the USD Preview Surface material with textures.

Viewport Performance Rollout

One interesting feature of the USD Stage object is the Viewport Performance rollout which gives control over “consolidation”. Consolidation is a technique for better viewport performance by merging/attaching multiple objects before sending the mesh data to GPU. Nitrous also uses this technique heavily. “Mesh Merge” option lets you choose to consolidate “Static” mesh or “Dynamic(animated)” mesh or to turn “Off”. You can also control “Mesh Size threshold” and number of meshes to merge(“Instances”)

There is no single optimal setting that works across all scenes. Consolidation is not free, and the consolidation cost could be bigger than the benefit. You kinda need to play with the settings. For example, the scene in the following image originally has around 5000 baked animated objects from a Thinking Particle setup. The original scene and Mesh Merge Off were playing at 13.7fps. When I set it to Dynamic merge with 1000 threshold. I got 45fps. To help users to get the best setting, Visualize checkbox is provided so you can see how consolidation happens.

Display Purpose

Purpose is a unique concept of USD. Each prim in a USD file has a purpose. As the name suggests, it defines the purpose of the prim. If a prim is for the final rendering, you set it as render purpose. Prims for fast viewport display can be set as proxy purpose. Prims that is not supposed to be rendered similar to helpers in 3dsMax would have a guide purpose. Some of you may remember that I mentioned that all bones and non-renderable objects with shapes are exported as guide purpose automatically. If no purpose is set for prims, they will fallback to default purpose which means the prim has no special purpose. 3dsMax Stage object and USDView both set to not display render purpose by default.

To set the purpose, you need to add “usd_purpose” custom attribute, and the value needs to be a string. In the following image, I used Parameter Editor to add the custom attribute on an Attribute Holder modifier and copy/pasted the modifier and set the purpose.

Stage object has “Display Purpose” option in “Viewport Display” rollout. You can toggle on/off Guide/Proxy/Render purpose prims. Invert button will provide a quick way to on/off between Render/Proxy. Default prims will be shown all the time. Obviously, this requires some setup on the user side. You could auto-generate a proxy with some scripting, or you can use cut-up geometry for the rig as a proxy.

Rendering USD Stage

Just like displaying USD data, the rendering of USD should be also handled by renderers directly. Thanks to the industry-wide support/hype(?)/pressure many major renderers like VRay, Arnold, and RenderMan already support the native rendering of USD.

Also, there is Hydra, an open source framework to transport live scene graph data to renderers. In English, it is a plugin API for rendering USD. If a renderer has a Hydra delegate, it can render USD scene. There are a few free Hydra render delegates such as AMD Radeon ProRender, Autodesk Aurora, DreamWorks MoonRay.

As a user, using and rendering USDStage objects is pretty much the same as using and rendering .vrscene objects, and you can expect most of the same benefits of using renderer’s own scene file format. For example, this is the VRayCryptomatte render element for the NVIDIA Attic scene. Even though it is one Stage object in 3dsMax, you can see that VRay generates a mask per prim.

Here is the currently supported USD feature list for VRay and Arnold. If you see the VRay list, you can tell that the list is pretty much the same as the supported feature list for vrscene.

You can also mix USD Stage with Max native object in the same scene. Again,it is just like using vrscene or Arnold Procedurals. In the following image, I added a VRayLight and Teapot and rendered it with Pixar’s Kitchen USD file. You can see the GI, shadow and reflection between 3dsMax teapot and USD prims intersect each other seamlessly.

OK, then, why should I use USD over vrscene if it does the same thing? Let’s see some interesting USD features.

In-memory Stage Data Modification, Variant, USDSkel

One of the cool features of the USD Stage is in-memory Stage data modification. After you load USD with Stage object, you can change almost anything there. USD for 3dsMax doesn’t have any UI for this YET. But, you can still do it with Python today, and USD for 3dsMax comes with the full USD Python binding.

You can hide/unhide prims. You can move around prims. You can change purpose. You can add prims. You can do anything. You don’t need to ask anything to 3dsMax nor renderer developers. You can just do it. The following image shows I just hide the half of walls in the Attic USD file. This change will be saved in the session layer, and it can be saved out as a file or even stored in the 3dsMax scene.

What does it mean? It means that you can have the flexibility of comprehensive editing while benefiting from the performance as an external reference.

I understand that all these may not sound exciting or really sink in yet since we don’t have any UI for this. But, I’m sure we will see the editing UI from either Autodesk or 3rd party(renderStacks :)) at some point. Or, if your studio has a pipeline dept, they can build USD land using Python right now!

Another unique USD feature is the VariantSet. VariantSet is a set of variants(duh). This is like the new Material Switcher material which was added in 3dsMax 2024. Material Switcher allows you to have multiple different materials and choose one of them to use. VariantSet is the same. It has multiple variants. You can choose to use one of them. A variant can be anything. It can be a prim or prims, or It can be a big USD tree or material.

Lastly, there is USDSkel, Skin and Morph animation. Basically, instead of caching every single vertex position, USD caches bone animation skin weights just like FBX does. The benefit is obvious. The file size is a lot smaller. This scene has about 300 animated Populated agents and 411k verts. When I exported it as deforming vertex animation for 280 frames, the USD file size was 3.2G. When I exported it as USDSkel, it was 354M. Almost 1/10 size. It even plays faster. USDSkel version is playing at 30fps while vertex deformation version is playing around 24fps. The original 3dsMax was playing at 9fps.

Waiting for godot

“Wait a min. I heard that I can save a Maya/Arnold scene as USD and render in 3dsMax/VRay and get the exact same render if I use USD. Why don’t you mention that?”

Well… NO! Sorry. But, that’s not happening. It doesn’t work in that way.

Let’s think about what we need to get a rendered image. We need to define the shapes of things(geometry) and the look of things(material and light) and the movement of things(animation). The geometry and animation parts are relatively straightforward. There are well-established ways for presenting polygonal and volumetric data. Animation is even easier since they are a series of transforms of nodes/vertex or snapshots of geometry for each frame.

But, material and lighting are not that simple. Let me show you a very single example. This is Checker, OSL:Checker , and Arnold Checkerboard maps. Probably the simplest map we can imagine. Check the following image, all 3 have different sets of parameters. Checker map doesn’t even have a parameter to set the number of tiles. OSL:Checker uses one “Scale” value for both u and v direction. Arnold Checkerboard has separate values for u and v.

Now imagine you have a checker map in the middle of somewhere here. Having a different value or missing a parameter could produce a completely different render. To get the exact same render result, you must have every single node in the image for VRay and Arnold, and all of the maps must calculates value exactly in the same way. That sounds very impossible.

It doesn’t matter if USD can store all the parameters in an USD file or not. Storing the data is not a problem here. You can do that easily with .xml or .json or even .ini, and many of pipeline folks have done this for years and years even before USD was born. NO. USD doesn’t help anything here. It doesn’t bring anything new to solve this problem.

To make this happen, we need a well-defined shader standard that can cover a wide range of feature sets. Then, all renderer dev must agree to strictly follow the standard which means literally using the same code. Oh, wait. There is one, MaterialX! Yes, indeed. MaterialX is aiming to solve this problem. It provides a wide range of features and actually generates shader code for multiple different targets. So, it is certainly better than using baked-down bitmaps only material standard. But, check yourself since MaterialX is now in 3dsMax. The current shaders that are provided by MaterialX are nowhere near production-ready enough. Also, there are shaders, such as AO or Curvature shader, that rely on the features of the host application or renderers. Those shaders can’t be really standardized to have a pixel-match result. They would also need its own optimized code for each renderer or host application to be production worthy.

Also, this means renderer developers can’t really add any new shaders by themselves. If you want any new shader, you will need to ask MaterialX folks and wait until it is included in MaterialX spec. Then, you will need to wait for the support of the new MaterialX version for your DCC and renderer. Then, make sure all the parties you are working with upgrade to the new version. For example, Let’s say you used the “awesome” shader that’s added in the latest and greatest version of MaterialX 13.21 because you are using 3dsMax 2040. But, the other studio you are working with is still using Maya 2035 which only supports MaterialX 12.18. They will not be able to render the “awesome” shader.

A common standard NEVER means the best of all. It always means the least common denominator. You will need to sacrifice flexibility and features over compatibility. Some industries may value compatibility over flexibility. Some would not. How about you? What’s more important for you?

Lighting is in the exact same situation. Yes, USD has UsdLux(USD Lighting Schema). But, it doesn’t work as of today as Anders Langlands stated, “Different renderers produce very different images for the same USD due to differences in how certain lights are interpreted.”

Let me repeat again. There is no way to save a Maya/Arnold scene as USD and just press render in 3dsMax/VRay to get the same render now. You can wait for godot if you want tho.

BUT! Yes, there is always BUT! If your goal is sending material/lights for the same renderer between different host applications. You have good news. In this case, USD kinda works because the renderer dev knows what data to save and how to use the data exactly. I mean vrscene can already do that. You can save vrscene from Max and render in Maya or Vantage and get the same result. The following image is a comparison between a render of VRay proxy and a render of USD Stage object. This asset is from Chaos Cosmos which was originally a VRayProxy object. It was converted as an editable mesh and exported as USD. You can see the render is almost the same.

Material Override

In the end, If we are rendering the USD data in 3dsMax, why not just use native renderer lights and material in 3dsMax? Then, we don’t need to be limited by MaterialX or USD Preview Surface material or USD lights.

Lights are easy. Just make VRay/Arnold lights and set parameters and place them in the scene. As I showed in the Pixar Kitchen render.

Overriding material would need a more involved workflow and UI. But, our friend at Chaos is planning to give us something sooner. In the latest nightly VRay build, you can override materials in USD Stage objects using Multi/Sub material as UI. It is actually almost same as the fallback mode I’ll cover next.

In the following image, I downloaded fender_stratocaster.usdz from Apple and unzip the file and loaded it as a Stage object . USD for 3dsMax doesn’t support direct loading of .usdz. But, .usdz is literally just a zip file. You can unzip with any zip utility and load the USD file in there..

This USD file has total 20 materials. I overridden just one of them. All I need to do is to set material path “/fender_stratocaster/Looks/pxrUsdPreviewSurface1SG” as “Name” of sub material(Not the sub materials’ name) and assign the material I want to use. In the image, I overridden with VRayCarPaint material.

This is a simple yet very effective workflow. Kudos to VRay folks! If you are an Arnold user, ask Arnold dev to have same thing. I’m sure there could be a more USD-like workflow. But, I prefer to have a more familiar Max-like workflow.

Fallback Render Mode

But, I’m a Corona renderer user, and it doesn’t support the native USD rendering yet. I’m still using VRay 5, and USD support is added only for VRay 6. Am I screwed? Well… no. I have good and bad news for you.

3dsMax dev implemented a fallback render mode for USD for 3dsMax. If the renderer doesn’t support the USD native rendering and requests render mesh for the Stage object, 3dsMax provides render mesh to the renderer just like any other object. Stage object also automatically builds Multi/Sub material for all materials in the file. You can even override materials! Many of you probably have used this kind of multi/sub material workflow for tyFlow, TP, and Alembic caches.

We can generate the multi/sub material for the Stage object using “Assign USD Materials” button in USD Render Setup rollout. The following image, I overridden the material of the body with a new CoronaPhysicalMtl and CoronaBitmap, and render with Corona renderer.

This is great news. But, we have a small problem for pre-VRay 6 and Corona users. I don’t know why. But, only VRay and Corona are having issues with smoothing group/.normal in the fallback mode.

This is the Toy Drummer USD from Apple and rendered with Corona using the fallback mode. If you render with Scanline or FinalRender. This doesn’t happen. I have already submitted a ticket. But, if you are a Corona user. You should ask to fix this, too.

Animation control

As a container which support animated cache, USD Stage also has controls for animation playback. The options are similar with Alembic playback options. But, USD has my favorite new option, Custom Start & Speed.

USD uses TimeCode for their time unit instead of frame. So, Stage object will adapt to your scene fps setting regardless of the source USD file’s fps. Stage object will show the original USD time code and how it map to 3dsMax time.

One thing you need to know is that the Source Info is the reading of metadata in the USD file. If a USD file doesn’t have correct information, you will see the incorrect information as is. But, if there is animation data, the Stage object plays it correctly regardless of the displayed number.


OK, I think that’s enough to read for the USD Stage object for now. I think this is my longest blog post ever. But, there are still a lot more to know about Stage like how to edit and composite. I’ll have a new article as USD editing workflow comes into USD for 3dsMax. For how to assemble(composite) an USD scene, you probably have to learn by yourself.

USD provides various ways to composite Stage such as sublayer, layer, layerstack, reference and payload. Personally, I don’t think an “artist” should know or care about any of these. If you work for a studio which is big enough to care/utilize these, they should have a dedicated pipeline developers to handle all these and just expose some UI for you. If you are a freelancer or work for a small studio, you are probably ok with just assembling Stages in 3dsMax just like you were using vrscene/proxies. In the end, there is no right or wrong answer about how to use USD. It is just another tool. You should just use as you need and a way that you feel comfortable.

Lastly, here is s video which shows some of what I mentioned in action.


USD in 3dsMax #1 – Export

USD for 3dsMAx 0.5 has been released. You can see how it has progressed in the What’s new section of the official documentation. Even tho it is still in a beta stage, it is actually pretty production-ready in terms of both features and stability.

I think it is a good time to review what USD for 3dsMax can do at this point. Also, we probably need to have some time to understand what USD is, how different it is compare to other data exchange formats. USD is a little bit complicated animal. Then, we also need to see what kinds of new workflow it would bring.

So, I decided to have a few blog post about the current status of USD in 3dsMax. I originally just try to have one post. Then, it was getting too long. I decided to split to multiple post. This is #1 – Export.

So, what is USD?

USD stands for “Universal Scene Description.” It is a system for encoding scalable, hierarchically organized, static and time-sampled data, for the primary purpose of interchanging and augmenting the data between cooperating digital content creation applications. USD also provides a rich set of composition operators, including asset and file references and variants, that let consumers aggregate multiple assets into a single scenegraph while still allowing for sparse overrides.

It is a bunch of C++ libraries and specs for making a scene assembler. This is why it is called “Composition Engine”. Yes, it also provide data exchange format. But, that’s just part of USD. Pixar even said it is not just another file format. NVIDIA Omniverse is an implementation of this library as an application.

Therefore, utilizing USD is not exactly same as using Alembic or FBX. Yes, you can just simply use as another data exchange file format. But, you can also take advantage of new possibilities to improve your workflow(not necessarily reinvent your workflow). USD world is big and complicated. Keep in mind that this is made by Pixar for Pixar. There are a lot of Pixar-ness in it which is not necessarily align with a 3dsMax users. You can start with learning some concepts and terms.

You don’t need to feel pressure of “I must use USD because it is the future”. It has its own pros and cons. In the end, it is just a tool, you just need to utilize as you need.

Lastly, I must admit that I’m not an expert on USD at all. I just learned while beta testing USD for 3dsMax. Just take my post with a grain of salt.


USD is a scene assembler, so we gonna have some data to assemble, right? USD actually can read some existing file formats such as Alembic and Obj. But, even Alembic is not enough to store all the data that USD need to store. Also, it wouldn’t be 100% efficient for new framework to use legacy formats since they were developed before USD developed. Therefore, USD also provides a very comprehensive data exchange format.

It supports mesh with various attributes, transform animation, deformation animation, topology mesh changing animation(like Alembic), and also skin and morpher(like FBX). It can also store lights and cameras with more parameters, shader trees and more. Think it as Alembic + FBX and more. BUT! Remember it is still all BAKED CACHE. It can’t store a live character rig. It can only store baked transforms. Like it or not, this is the only way to achieve Interchangeability. No, you can’t rig in Maya and use it in Max. It will never happen. No, you can’t keep the modifier stack from Max to Maya. It will never ever happen.

Since 3dsMax is primarily a “Digital Content Creation” program,The development focus for USD for 3dsMax has been more on generating USD(Export) than consuming(Import). In this article, I’ll go over where we are at for exporting USD data. You can find the official document here.


  • Obviously you can export your mesh/geometry.
  • Mesh Format – You can choose to export as Poly(Convert to Polygons) or Trimesh(Convert to Triangles) or as is in the scene(Preserve Existing). If you wan to export everything as you see in the viewport, use Convert to Polygon to since USD doesn’t care hidden edges.
  • You can choose to Bake Offset Transform(You shoudl always) and Preserve Edge Orientation by converting curved faces in your scene to trimesh.
  • Normal – can be exported As primvar or As attribute or choose not to export(None)
  • Vertex Channels – As you can see, all UV and vertex color channels can be exported as PrimVar.  One cool thing about this implementation is that you have complete control over which channel to export with what name and type.

Wait a second. Let’s take a break here. I have very important thing to mention. When you import/export between application using a data exchange format, both import and export need to work together. Even tho your exported data is perfect, if importer is not good, you will NOT get all the data correctly.

When the formats were very simple like .obj, it was easy since it carried very limited data such as static mesh, normal and single uv. FBX was more complicated format. But, it worked ok because it was closed format and everybody had to use the the same SDK.

When Alembic came out, all hell broke loose. It can have all kinds of data. But, it didn’t have much of spec or standard about what the data means. For example, Alembic only has one official uv channel. Other uv can be saved and loaded using arbGeomParams. But, as the name suggest, it is arbitrary. There is NO agreement on what would be uv channel 2. There is no spec for what vertex color channel name should be. Every DCC have their own way of export the same data! The data is there for sure. But, either it can’t be loaded or loaded incorrectly. I still have PTSD about this because I had to deal with this as a pipeline guy. When 3dsMax dev worked on Alembic in 3dsMax 2019, I had to make sure to have at least some control over it. So, when I heard about USD, I had high hopes. Maybe, maybe, finally, we might have a solid spec. Well, I was wrong. The situation is not any better. I don’t think there is even a standard name for uv. It has been changed a few times for USD for 3dsMax, and currently the name is “st”. See? The above image was not that long ago, it was “st0”!

This is why the custom primvar setup option is important. At least, you make USD file that other side is expecting.

  • Material ID – will be exported as GeomSubset.
  • Wireframe color will be exported DisplayColor primvar
  • Non-renderable object(Renderable object property off) exported and Bones/Biped/CAT will be exported as Guide purpose which means they do not render, and by default are not shown in USDView.
  • usd_purpose/usd_kind – custom attribute to set purpose and kind
  • Instanced geometry will be exported as instamced.


  • Standard (Physical, Free and Target cameras), 2 types of Vray cameras, and 4 types of Arnold camera are supported
  • FOV, Focal Length/Lens Breathing(Focal Length)
  • Projection Type(orthographic / perspective)
  • Clipping Planes/Range
  • Target Distance(Focus Distance)
  • Horizontal / Vertical Aperture/Zoom(Horizontal / Vertical Aperture)
  • Lens Shift(Horizontal / Vertical Aperture Offset)
  • Shutter
  • Exposure


  • Photometric Light
  • Color, ColorTemperature(value and on/off), Exposure, Intensity, Normalized on/off, Shadow(color and on/off), Shape, Diffuse. Specular
  • Photometric SunPositioner exports to USD including sun orientation, mapping color and intensity.


  • If Enable in Viewport/Rendering is off, spline will be exported as UsdGeomBasisCurves.If the option is on, it will be exported as UsdGeomMeshes.


  • Exported as Transform node


  • Node Transform animation – usual moving objects
  • Vertex Deformation – Non-vertex count changing mesh animation like point cache
  • Changing Topology animation – Vertex count/topology changing messh such as meshed fluid.
  • Skin/Morph Targets as USDSkel – just like FBX skin/morph export
  • Spline animation including vertex changing spline


  • USD Preview Surface – Dedicated USD Preview Surface material
  • Physical, PBR Material (Metal/Rough), PBR Material (Spec/Gross) will be exported as USD Preview Surface
  • Bitmap map, OSL BitmapLookup, OSL UberBitmap are supported.
  • MaterialX shadier as reference -If object has MaterialX material assigned. The file path will be referenced. This means whatever change you made in 3dsMax material editor will NOT be exported unless you save the file.
  • I know you have some questions about Material in USD. I’ll talk about it in the next post.


  • Stage is a composed USD scene. In 3dsMax, you can have a Stage object which containes the content of a USD file. l explain about this when I explain how to consume USD in 3dsMax.
  • USD Stage objects or prims are exported as USD references. It is similar to nested scene xref. It is very similar to a nested scene xref.
  • Because the Stage objects are exported as a file reference. Any in-memory change or animation setting change in the scene will NOT be reflected in the exported USD file. Same as MaterialX.

As you can see the most major data types for any traditional productions are already all supported. There are a few missing ones. But, I’m sure they will come in the future. But, how about all the 3rd party plugin data? What if I need export something right now? Well, lucky for you. There is very easy way to make own exporters.

PrimWriter, ShaderWriter and Chasers

3dsMax USD SDK allow you build your own PrimWriter(scene nodes), ShaderWriter (Materials) and Chasers using either C++ or Python to hook into 3dsMax USD Exporter.

Prim writer/Shader Writer

Prim writer will execute for each Max node at export-time. So the exporter iterates through all the objects to export, and each object it checks the current list of registered prim writers for the first prim writer that says it supports exporting an object. If one is found, that prim writer will export that specific node into USD and other prim writers are now skipped.

In English, you have control over how to export each object type(class). For example, if your renderer dev is slow to support USD and you need to export the renderer’s camera right now. You can do with a little bit of Python. In SDK, there is a a sample prim writer,SpherePrimWriterSample, which export 3ddMax sphere as USD sphere with a radius value.

Shader Writer does same thing for materials.


Chasers happen at the very end after all prim writers are done, and contain a mapping of the original Max nodes and the resulting USD prims. This allows you to append data to things already written.

For example. the current version of Exporter can’t export objects properties or user properties. But, in SDK sample, there is already an exporter does that, UserDataExportChaserSample.

If you Chasers, it will show up in “Plug-In Configuration” drop down.

File Format


USD supports Binary(.usdc) and ASCII(.usda) format. The recommend USD workflow is having a lot of granular USD files and composite them as UsdStage. This is an image from Pixar.

It is recommended to use .usdc for data heavy asset data and .usda for composition. Remember 3dsMax USD exporter support exporting loaded Stage objects as references?

.usda is also very useful when you need to debug your export.


.usdz is zip-compressed package file format. To export as usdz, just give .usdz extension in the Exporter.


3dsMax USD includes USD python binding and various pre-compiled toolsets. One of them is USDView. They are here. C:\ProgramData\Autodesk\ApplicationPlugins\3dsmax-usd-2024\Contents\bin

If you just drag and drop an USD file into, C:\ProgramData\Autodesk\ApplicationPlugins\3dsmax-usd-2024\Contents\bin\RunUsdView.bat file.  But, this file has to be in this folder. If you run form anywhere, put this line as a .bat file. Then, you can put this batch file anywhere and drag and drop an usd file to view.

"C:\ProgramData\Autodesk\ApplicationPlugins\3dsmax-usd-2024\Contents\bin\RunUsdTool.bat" usdview %1

This utility is a god send for troubleshooting. You can see everything in the USD file. I’m not sure if you really want this much tutorial, But, NVIDIA has USDView tutorial here.

Another very important use of this utility is that it serve as a ground truth of your USD file. When you send and receive a data exchange file, the importer and exporter both need to work properly. When something is not right, it could be a fault of exporter or a fault of importer. When I use Alembic, I have had to deal with so many “Why can;t 3dsMax read this alembic? 3dsMax alembic is not good”. Well, guess what? In most cases, the problem was the exported alembic file.  Either it was not following the needed naming convention or just badly organized data. Sure, it would re-imported correctly to the program which exported the file. That doesn’t mean that the file is sound!!! With this USDView utility, you can examine every single aspect of the USD file and find what the problem is. If this utility can’t read the USD file. Then, the file need to be re-exported. Period.

What’s left

I can say that, as of today with, USD already can do more than Alembic. Also, Arnold and VRay already started to support own exporters, and the Prim/Shader Writers and Chaser even allow you to implement custom exporter easily. So, you can certainly use 3dsMax for authoring USD data in production. Just try it.

So,what’s left in terms of export?

  • Velocities channel – This need support from 3dsMax dev.
  • Animated Custom Data – We already can  export static values for custom attributes, user properties and other node properties for artist with Chaser. But, we arew waiting animated vale export support from 3dsMax dev. We need UI forartists.
  • Variant Set – This is a unique concept of USD for switchable reference(Variant). It could be low/high res or different combination of parts or different materials. You can actually do this with Prim Writer if you need. But, we will need UI for artists.
  • PointInstancer – This also can be made with Prim Writer if you need. But, we will need UI for artists.

OK, I guess this is it for export. I’ll talk about Stage object in next post.


MaterialX in 3dsMax

The USD for 3ds Max 0.5 release adds full support for MaterialX to 3ds Max. You can load, import, edit, create, and export within 3ds Max using native tools.

So, what is MaterialX? According to, it is…

MaterialX is an open standard for representing rich material and look-development content in computer graphics, enabling its platform-independent description and exchange across applications and renderers.

MaterialX addresses the need for a common, open standard to represent the data values and relationships required to describe the look of a computer graphics model, including shading networks, patterns and texturing, complex nested materials and geometric assignments. To further encourage interchangeable CG look setups, MaterialX also defines a large set of standard shading and processing nodes with a precise mechanism for functional extensibility.

So, it is an open standard for material. It is a specification, an explicit set of requirements. Any renderer that follows this spec should give the same result for a MaterialX document. We could author a MaterialX material in 3dsMax/VRay, render in Maya/Arnold, and get the same result as long as we follow the spec. I’ll talk about it later again.

This update allow users to 1)Load MaterialX document 2)Render them with any renderer that supports Physical material/OSLmap(All CPU renderer and supported GPU renderer) 3) Edit the loaded material/maps 4)Author MaterialX material from scratch 5)Export as MaterialX document and 6)Export as material binding when export USD file. What do you need more than this?

Now why is MaterialX released as a part of USD for 3ds Max? This is because MaterialX is emerging as a material standard for USD. USD has UsdPreviewSurface. However, it only supports a very basic bitmap-based material tree without more advanced features such as subsurface and anisotropic specular highlights. Also, Material X has its own XML-based file format which goes along well with USD. USD loves files.

Let’s see how it actually works in 3ds Max.

Loading MaterialX

As I mentioned, MaterialX has its own file format, and the new MaterialX Material allows loading this .mtlx file.

As you can see, .mtlx file supports multiple materials in a file, and you can choose a sub-material from the dropdown.

OK, that was easy.

MaterialX Import/Export Utility(MtlXOIUtil)

Another way of bring MaterialX into 3dsMax is using the new MaterialX Import/Export Utility(MtlXOIUtil).

Press “Import MaterialX…” button and choose a .mtlx file. Then, the MaterialX materials are imported and assigned to the selected objects.

If you have not selected objects or selected less objects than materials in the file, this utility will automatically created teapots and assign the imported materials on them.

If you choose a material library file(.mat) and check “Add to Material LIbrary”, imported materials are stored in the material library. They will be imported(exploded), Physical material not MaterialX material.

“Populate Material Editor” will put imported materials in the material editor slots.

Editing MaterialX

MaterialX in 3dsMax is implemented using Physical material and OSL maps. I heard that one of the reasons for adding OSL map support to 3dsMax was actually part of the grand plan for this initiative.Therefore, you can edit MaterialX material tree just like any other 3dsMax materials/maps using CME or Slate. This also means that any third-party renderer that supports 3dsMax Physical material and OSL map will be supported automatically.

MaterialX material provides 2 ways to edit the material tree.

  • Explode Permanently – Pressing this button will convert the MaterialX material to Physical material + OSL map setup. The MaterialX file loader material will disappear from Slate and the new Plysical material will be assigned to the objects.
  • Open for Edit – Pressing this button will make a new tab with the Material node name(Not the MaterialX file name. The 3dsMax Material name) and put exploded material tree there. As you can see, the MaterialX material is still assigned to the objects(the white triangles around the corners show that). But, any changed on the material tree in the new tab will be applied to the objects.

Authoring MaterialX

If we can load and edit a MaterialX shader tree, well, that means we can make one from scratch, too. I mentioned any renderer that supports MaterialX will give us the same result for Material materials as long as we follow the spec.

MaterialX certainly can do more than bitmap-only-based PBR material. It has a bunch of Standard Library Nodes, and 3dsMax MaterialX supports them. Would this set of nodes cover all your production needs? Well, see for yourself. Here is the spec document. You will probably need to sacrifice the flexibility and features for compatibility. “Standard” always means the least common denominator. It will never be the best of all. But, When you need it, you will need it. Having good comprehensive support for such an open standard is a good thing.

Let me say it again. A material standard only works when you follow the standard exactly. Even one parameter difference in the shader tree can make totally different result. Some might want to have an automagic converter for all our 3dsMax maps and 3rd party maps. But, doing that will open a can of worms. I rather have a clear explicit way to author MaterialX when I need MaterialX.

As I mentioned, this MaterialX support is implemented by Physical material + OSL map combo. Therefore, only Physical material is supported for the material. The good thing is that most 3rd party renderers support Physical materials which means they will get MaterialX support automatically.

For maps, there are MaterialX maps category under OSL. You can find 1:1 MaterialX Standard Library Nodes here.

 Here are a few things you need to know.

  • 3dsMax “Normal Bump” can be used for MaterialX “normalmap”
  • Each data type has its own map. For instance, there are 4 “acos” maps for float, vector2, vector3, and vector4. This may seem tedious, but in my experience, it actually makes it much clearer which data type I am currently working with. If you use the wrong data type, MaterialX will simply not export those invalid trees.
  • Make sure to use “color” type for color. Never use “color” type for data. All color-type maps will be color-managed. This means you can’t load a map and use it for baseColor and Roughness. You must use 2 separate texture nodes to load one as color and another as data.
  • Bitmap material is supported. But, only the filename will be used. If you want to adjust tiling and offset, use “mx_image” or “mx_tiliedimage” maps.
  • If you want to know what each map does, check the MaterialX spec document.

This is what I made in 3dsMax using Physical material and

And loaded in QuilitiX

Hers is another good news. 3dsMax has a few specialty materials that use Physical material under the hood. If you use any of these materials, you can exported them to MaterialX.

  • PBR Material (Metal/Rough)
  • PBR Material (Spec/Gross)
  • glTF Material
  • USD Preview Surface Material.

Exporting MaterialX

You can export the new/edited materials using MaterialX Import/Export Utility(MtlXOIUtil). Just select objects with materials to export and Press “Export MaterialX”

If there are multiple materials in the selection, all those materials will be stored in a .mtlx file.

Make sure to check Maxscript LIstener for validation checks. Your material tree might not be valid. If you see warnings, you must fix them to export properly.

Integration with USD

The MaterialX plug-in comes with a Shader Writer for the 3ds Max USD Plug-in that will allow the USD export to bind references to the MaterialX files to USD Prims when exporting scenes using a MaterialX Material.

Here is a short video of MaterialX in 3dsMax in action.

How to manage tools part 2 – Plugins (featuring new 3dsMax 2022.3 pipeline integration)

This is the second part of how to manage tools series, Plugins. I’m sure most 3dsMax users know about the plugin,ini file. When 3dsMax starts, it looks for the following 2 plugin,ini files.

  1. C:\Program Files\Autodesk\3ds Max 2022\en-US\plugin.ini
  2. C:\Users\[username]\AppData\Local\Autodesk\3dsMax\2022 – 64bit\ENU\Plugin.UserSettings.ini

This is a usual ini file with sections and keys and values like this.

Additional MAX plug-ins=C:\Program Files\Autodesk\3ds Max 2022\PlugIns\

You can edit one of the above files with a text editor to add your own plugins folder or use Customize menu > Customize Users and System Paths dialog > 3rd Party Plug-Ins tab.

Usually a commercial plugin would have an installer to take care this for users. Then, users would make a plugins folder and throw all free plugin there and add the path to plugin.ini. Or, some still just throw everything in C:\Program Files\Autodesk\3ds Max 2022\Plugins folder. If your studio has TDs or IT department, they probably already have their own way to do it. Also you can specify a plugin,ini to use via command line option -p while launching 3dsMax

But, there are also 2 not-so-well-known ways of managing plugins to know.

  1. [Include] section in plugin.ini
    This allows to nest plugin ini like this image.
    This is great for central management and exactly the same principle as my “seed startup script”. You just deploy a caller and do the real job in another file. This is what I have been using.
  2. Autodesk Application Plug-in Package
    This is the new official way to distribute any plugins and a great way to de-couple plugin files from 3dsMax installations. VRay already has moved to this method and hopefully more commercial plugins adapt to this format. But, you can also utilize this for your own plugin management. It is a little bit involved. So, it might not be great for individual users or small studios. But, if you have TDs or IT department, it is worth checking.


The new pipeline integration also supports custom plugin and application package folder. You can use these two following env vars to control plugin loading location. Again this means I don’t need the seed .ini anymore!


But, one thing you need to understand is that the current pipeline integration in 3dsMax 2022.3 is mainly aimed for using a batch file or Python script. Because of that, it doesn’t have a way to specify the 3dsMax version. That means all 3dsMax versions will pick up the exact same folder when you have multiple versions installed. This can cause problems if any folder you set has version specific data likek plugins folder. As you know, often plugins are not compatible between versions, if you set “ADSK_3DSMAX_PLUGINS_ADDON_DIR” as system env var, all the 3dsMax versions will try to to pick up plugins from the same folder. That wouldn’t work.

With 3dsMax 2023 updates, the above issue has been addressed. Please check the new post here.

Therefore, you need to set env var only for a session instead of the whole system. You can do this by using a batch file or Python script to run 3dsMax. If you have a Python launcher, you probably wouldn’t need a tutorial from me. Here is a sample batch file for “artists”. A good thing about this sample is that it doesn’t leave the command shell after 3dsMax started.

SET ADSK_3DSMAX_PLUGINS_ADDON_DIR=D:\PROJECT\_maxDefault\plugin_free_2022
cd "C:\Program Files\Autodesk\3ds Max 2022\"
start "" "C:\Program Files\Autodesk\3ds Max 2022\3dsmax.exe"

“SET” command is the command to set env var in a batch file.

As you can see, this allows you to define the combination of plugins dynamically while launching 3dsMax easily. Imagine you need different versions of VRay, ThinkingParticles per project. Before the pipeline integration, you would need to build a plugin.ini per project and load. Now, you can just add directories directly in the launcher script.

This is it for plugins! But, the potential of the pipeline integration doesn’t end here. WIth new env var controls and token support in various ini. You can actually install each PUs side by side now like 3dsMax 2022.1, 2022.2, 2022,3. You can even install 3dsMax in a network folder and load from there. Sure, you need to figure out how exactly execute this for your studio. But, the technical foundation is there. So, try it!

Do you want to improve your pipeline? renderStacks could be the start.


3dsMax 2022.3 Highlights

3dsMax 2022.3 has been released with new/improved features and fixes. Here are some highlights. Please check Unofficial 3dsMax What’s New for all 3dsMax updates in detail!

Advanced Wood OSL shader

As an OSL shader, UVW can be modified with external shaders, and a random seed can be driven to have per-object variations.It is also fully supported in a ‘High Quality’ viewport and will render exactly the same on any OSL capable renderer.

Per-Viewport Filtering

You can hide/unhide objects by category or by class per each viewport. Each viewport’s settings can be set independently from one another, giving you the flexibility to display what you need in a given viewport. Per-Viewport Filtering does not affect the scene or renderer. User can copy/paste filter setting between viewport. Shift+K to toggle on and off the viewport filter Full MXS exposure with ViewportFilter interface. Per view settings/preference dialog is modeless and dockable now.

Pipeline Integration

You can control most 3dsMax path with environment variables. This reduce the need of extra file deployment. It also allow you have more flexible setup like different plugin configuration for same version easily.Support for Environment Variable Tokens in Paths found in Configuration Files.

Occlude mode – marquee(box)/paint selection support

High-polling rate mouse fix

Save Performance Improvement 2

We got the second round of file save performance improvement.,This is the sheet I made during beta testing. As you can see, 2022.3 saving is 20-40% faster on top of 2022.2. The % number in the table is how much it is improved. So, 100% means 2 times faster. 200% means 3 times faster.You can see some of big files are saving more than 4 times faster than 3dsMax 2016.

Autodesk Official Site
3dsMax 2022 What’s New
3dsMax 2022
Release Notes
Maxscript What’s New

Make your rendering life awesome with renderStacks 2!

3dsMax 2021.3 Retopology Modifier Quick Start – Part.2

OK. Part.2! In this post, we will focus on object with hard edges like booleaned model or CAD data.

Booleand Model

Booleaned model is usually pretty easy. Applying Retopology modifier, set the target number and pressing Compute is enough.  But, again it might fail sometime, and you simply want to get better result. So, here is some tips for booleaned model.


  • Utilize Boolean Seams for very low angle sharp edges
  • Regularize option can help to get more even quad distribution and prevent spiral loops.
  • Adding Subdivide modifier can help a lot to solve and get better result.
  • Having some support edges helps to get better edge flow. Especially for flat circular shapes.


Here is an example. I just apply Retopology modifier, set target to 3000 and just pressed Compute. Auto Edge was on with Smoothing group by default. We got something . But, the topology doesn’t look that great, especially the center circle.

So, I went back to the center boolean operand and give some Cap segments. You can see it makes better edge flow on the big one circular ngon.

Or, you can just add Subdivide modifier. I usually use “Adaptive” option with default. You can see the edge flow is a lot better for both center circular area and front flat face.

Let6’s see one more example. For this kinds of source object, you must Subdivide.

The Retopology result looks good. But, it has an issue. It created the infamous spirals.  I fixed with by increasing Regularize to 1.0. Again this option doesn’t guarantee to remove all spirals. But, certainly worth to try.

CAD Data

Source Preparation

I guess I don’t need to explain how bad models from CAD can be. You all already know. The new algorithms in Subdivide modifier certainly does great jobs for making more Reform friendly faces. But, the mesh has split edges and inverted normal and overlapped double faces what not. Reform nor Subdivide will fail. Until we have T-1000 to retopo, you still gotta do what you gotta do. Here are some notes on mesh preparation.

  • Weld split edges and unwelded vertex. Reform would now know if that’s real edge boundary you want to keep or just bad meshed. The easiest way to check this is applying Relax or TurboSmooth. You will be able to see split edge easily. Then, you could apply Vertex Weld modifier with Threshold 0.001 to fix it.
  • 3dsMax 2021.3 provide Mesh Cleaner modifier. Try that. It also fix some issues.
  • Check if normal is flipped between neighboring faces. Unify option in Normal modifier could help.
  • Delete very small random elements with only few polygons especially for scanned data.
  • Sometimes Quadrify modifier fixes bad topology since it rebuilds meshes. You can also try TurboSmooth with iteration 0.


  • If it is small part, you can just treat like booleaned model, But, if it has complicated shape, evaluate how much minimum target is needed with Auto Edge OFF.
    If the target is too low, Reform often cause “IPOPT maximum iterations exceeded” error” which means basically Reform saying “I can’t solve this.”. By turning off Auto Edge, you can quickly check how much target is needed.
  • When you Auto Edge, you need enough information within the auto edge boundaries. If you don’t have enough information, again you will meet “IPOPT maximum iterations exceeded” error”. To increase the information, there are 2 options.  1) Subdivide more 2) Remove auto edge condition. For example, if you use UV seams, you could stitch unnecessary seams. If you use Smoothing group, you can smooth some minor edges.
  • Check if your hard edge is coming from the smoothing group or explicit normal. If you only have explicit normals for hard edges and turning on only smoothing group means you don’t get any hard edges. If you are lazy like me,. you can just use Angle option instead of Smoothing Group or Specified Nornal option.
  • Sometimes model could have bad smoothing group and that prevent Subdivide modifier to work properly. Use Smooth modifier to clean up smoothing group.
  • Since Retopology doesn’t preserve mesh data yet. It will look all smooth after it solves. Apply Smooth or Weighted Normal to check hard edges.
  • Often CAD data has nice UV seams, utilize it.


This is a part from Fusion 360 sample scene. It had a unique problem. So, I thought that it was good example to show how I processed the model. You don’t have to go through like this for every model!

This is the source model.
The First attempt with Specified Normal. I got solve. but, I don’t like the edge flow.
I applied Subdivide modifier and set to Adaptive. OK.. something is wrong. I still see a lot of thin edges. This is because there are many smoothing groups there.
I cleaned smoothing group. Subdivide look better.
Retopoed again. Better edge flow. But, I want to improve.
Subdivided more and set Regularize to 1.0.

Then, I was thinking how about go lower res model and TurboSmooth?

This is 2000 target.
Chamfer and TurboSmooth!

OK, I shared all things I have learned during beta testing. If you think it is helpful. Please visit renderStacks!

Also don’t forget to check Autodesk Learning Channel Retopology Tutorial.


3dsMax 2021.3 Retopology Modifier Quick Start – Part.1

The new Reform algorithm in the new Retopology modifier in 3dsMax 2021.3 is a definitely one of the best automatic retopology tech on the market. But, this is not driven by crazy AI nor a silver bullet to solve everything with a click. You need a different approach for a different case to get the best result in short amount of time. This is a collected notes from my beta testing period. I hope you find it useful.

Scanned Data

OK. This is easy one. For any organic models, just 2 things.

  • Turn off Auto Edge. This is for preserving sharp edges for hard surface model.
  • Decimate with ProOptimizer A LOT. I mean really a lot. Usually the rule of thumb is matching ProOptimizer verts count to Target count gives you best result in the shortest amount of time.So, if you want to get 40,000 poly mesh, ProOptimized to 40,000 verts first the Compute. Think this way. if your target is 30,000 poly from 2 million poly source. You will not get all the details of 2 million in anyway. There is no reason to feed all those noise data to Reform.
  • If you want to retopologize to really high poly count to reserve all scanned details and Retopology doesn’t solve with that mesh, try InstantMesh mode as a pre-process instead of ProOptimizer. You can’t decimate as much as ProOptimizer with it. But, it generates more Reform friendly mesh. Therefore, it will give you a higher chance to get result.


  • If you want to process even faster? Then, apply Relax modifier before ProOptimize. You could get faster result in exchange of the loss of details.
  • After ProOptimize if you have very big flat polygon. Remove it or subdivide a little. This kinds of big single polygon can make Deform fail. I’ll show you in the following example.


This is scanned model from Konrad O?óg, Thanks for the model. It has 1.95 million verts and 3.9 million tris. Look at that beautiful wireframe on right. If you just apply Retopology on this and press Compute. It will takes days.

I applied ProOptimizer and went down to 2%, 39012 verts. As you can see from the shaded view. ProOptimizer does great job for reducing poly count while keeping shape intact.

Then, I had a hiccup. This big lowres place at the bottom was throwing a wrench. I could subdivide this. But, I simply delete it. You don’t see anyway. Also I can recap later.

I turn off Auto Edge and set Target Face Count to 40,000. After 100 second. I got this with 43,000 poly.

The following images are high resolution retopology example using InstantMesh as a pre-process. I pre-processed to 500,000 poly with Instant Mesh and Reformed it to 150,000. It took 20 min on Ryzen 2700X.

Original scan – 1.95 million verts / 3.9 million tri
InstantMesh – 475k verts / 494k quad
Reform – 163k verts(1/11 of original) / 162k quad

Do you want to make your render life 1000% easier! Click here!

Also don’t forget to check Autodesk Learning Channel Retopology Tutorial.