Menu Close

Long tutorial – How to build a pipeline for a small team

This will be a long tutorial. Be prepared!

I’m sure many of you already have used some form of pipeline or at least heard about it. Having a good pipeline could make your job easier, faster. It would reduce the burden of non-artistic tasks, and let you concentrate on making art.

If your studio is big enough to have dedicated TDs and engineers, you probably already have something. But, if you are a small team, the chances of having an automated pipeline would be low since it requires resources and effort. Or, simply you may not even know where to start.

I have had a chance to build a few pipelines from scratch and also have used a few existing pipelines, big and small. From those experiences, I want to share how I would build a new pipeline for a small team if I start again a small team.

Before we start, I just want to make sure that there is no “right” way for a pipeline. The best one is always the one that artists want/like to use, and every studio and every artist has their own taste. So, use this post as just a guide.

Does your studio have a rule for saving a max file and render outputs?

Let’s ask the first question. Does your studio have a rule for saving a max file and render outputs? If the answer is Yes. Then, you kinda already have a pipeline. You may not have an automated one. But, you certainly have a pipeline for sure. But, if it is not automated by code, a lot of benefits of having a pipeline will be lost. Humans simply can’t remember all those rules and execute the rules consistently all the time.

Consistency is the key for automation.

The first step for an automated pipeline can start from establishing a naming convention for project files and render output and making a tool for it.

Why? Because using a naming convention requires a minimum amount of coding. Sure, you can use custom DB or off-the-shelf solutions like ShotGun(Flow) or even xml/json. But, all these methods need to be coded and maintained by someone. If you don’t even have or can’t afford a TD, you probably can’t have a developer for this. Also, even when you could use these kinds of more advanced methods, it is good to have a solid naming convention.

Project folder and centralized storage

This workflow assumes everybody shares a central storage. In my 20+ years career, I never used project folders and have always used centralized storage. Considering a pipeline exists for multiple artists to work together, I’m not sure how the isolated project folder would work. So, this post assumes everybody has access to the same drive, either it is physically the same drive or synced.

Collect what kinds of information you need to define a task

Our goal is having a path and filename that would be unique per task.Then, we can add versions to the name. To get this, we need to collect what kinds of information is needed for a unique task. In this post, I’ll assume my studio is mostly working for episodic shows as an example.

To define a vfx task for episodic shows, you would need to know

  • Show name – The name of project or show like House, Airbender
  • Episode number – Usually you would combine season and episode as one entry
  • Shot name – each show name
  • Task type – Is it modeling? Lookdev? animation?FX?
  • Task name – each task of a task type

You can add more entries like artist name(I usually don’t recommend) or 2 level task name, But, I would have it as simple as possible.

This also can work for a feature film or commercial, you can use the episode entry for sequence. If it is a simple commercial or music video. You can just leave the episode as “000” or something.

Again, Keep it simple and unified. Don’t try to have exceptions and conditions. Yes, in the end, code can deal with all kinds of exceptions and conditions. But, the more parts you have, the more chance you have problems.

OK. The theory itself is simple. But, actually establishing a rule is not that simple. There are a lot to consider. Let’s get into the details.

Parse-able Filename

The first rule of a naming for codes – Never ever use space in the name nor path. NEVER! Trust me just don’t do it. Life is easier without space.

That being said, we can start by simply assembling each entry with “_” for the filename.  Something like this. Then, we can say that… “To get the information from the file name, split filename with _. Then, the first one is the show name. The second is the episode number, and on and on”.


Assembling filename by a naming convention is easy. But, the name also need to be pare-sable by code. Basically, we should be able to extract back the information that assembles the file name. In that sense, adding “_” between each item is not enough. What if your client wants to use “_” in a shot name? Like “24_56”? Then, the filename becomes like this.


Now filename parsing logic doesn’t work anymore because the 4th element from split would be “56”, not a task type. So, we need to have more complicated rules than just adding “_”. Good thing is that any code is very good at handling those complicated rules as long as the rule is clear and machine friendly. FYI, if you google “regex”, you can see what codes can do for parsing strings.

Let’s try a simpler logic. One of the common tool for establishing a naming convention is using special characters as separators to divide the filename into sections. Usually “_” and “-” are used for the separator because a lot of other special characters are an illegal character for a filename and path.

Now let’s think about which items we have more control over.

  • In my experience, there is a higher chance of possibility that clients could have their own naming convention for shots.
  • We have complete control over the task type since it is an internal stuff.
  • Usually project name and episode name could be a single word.
  • We need to have a good flexibility for the task name

With this requirement, this is what I did.

I used “-” as a main separator between task related items and others. So, I added “-” in front of the task type and decided not to use “-” in the task name. Then, we can say that “Separate filename divided at the last -”. Since the last “-” is the divider between task and else. You can use “-” in the shot name if you need. Something like this.


Then, split the front part with “_” and take the first item as a show and the second item as an episode.

HOUSE_201_24-56 – FX_Explosion_v001.max
Show_episode_shot –

Task part is even easier, split the green part with “_”. Then, the first item is a task type, and the last is a version, and the anything inbetween is task name. You can use any alphabet, number and underscore fore task name.

HOUSE_201_24-56 – FX_This_is_Your_Explosion_v001.max
Show_episode_shot tasktype_taskname_version.max

File Path Naming Convention

A file path convention is easier than a filename convention since we just need to put each item at each level. But, there are a few extra things to consider compare to the filename convention.

Let’s see my sample file path first.

Z:\Project\HOUSE\201\work\24-56\FX\This_is_Your_Explosion\max\HOUSE_201_24-56 – FX_This_is_Your_Explosion_v001.max

First, you will need a root folder. That’s “Z:\Project”. Don’t make it too long or deep.  Even tho we are making folders with code. The shorter, the better. Then, the show folder, “HOUSE”. Then, the episode folder, “201”. So far so Good. Easy.

But, what the heck is the “work” folder?

Currently we only have been talking about the project file, like max file and maya file, naming convention. But, you actually need a few different naming conventions for different things. For example, you can’t really use your max file naming convention for your render output. You will likely need more than one outputs, such as render element, from a max file. How about a published assets? If you build an asset publishing system, they will require a slightly different naming convention, “work” here means your working project files such as max and maya files, and we will put all project files under this sub folder.

Now you may wonder why under each episode? Why not under the show folder? Good question.

Your storage is expensive. You can’t store everything forever. At some point, you need to delete files. Even tho I do many things with scripts, I don’t really delete folders with scripts. You may think you made a perfect script for delete folders. But, imagine somehow your logic had a hole and all the project files for tomorrow delivery got deleted!

By having all your projects under the “work” folder under episode folder, you can clean up a project folder per episode easily. If you add this under show, you have to keep all projects for the show until the show ends or manually visit each episode and clean up. If you add it under the shot folder, you have to visit every shot to clean up projects files. Putting under episodes would be a happy medium.

We will talk later again. But, using the same logic, if we have “image” or “output” folder at the same level for render outputs and comps, you can clean up those folder first, and then clear projects later.

After “work”, continue just like file name, and the last folder would be DCC type or the project file format, and all versions for the DCC will be in the same folder.

Some might wonder why not have a folder for each version and have a DCC folder under there like this.

Z:\Project\HOUSE\201\work\24-56\FX\This_is_Your_Explosion\v001\max\HOUSE_201_24-56 – FX_This_is_Your_Explosion_v001.max

That kind of folder structure is usually for published assets which would have different formats for the same version all the time. For example, when you publish a model asset, you would publish an alembic file, a usd or a fbx along with your .max file. In that case, having the folder under the version folder would make sense.

But, usually you wouldn’t switch program between versions. If you ever need to switch to other program, you can just restart from v001.

OK, let’s see what we have again. This is the full path that I’m using.

Z:\Project\HOUSE\201\work\24-56\FX\This_is_Your_Explosion\max\HOUSE_201_24-56 FX_This_is_Your_Explosion_v001.max

  • Z:\Project – root folder
  • HOUSE – show(alphanumeric one word)
  • 201 – episode(alphanumeric one word)
  • work – project folder root
  • 24-56 – shot(alphanumeric & underscore & dash)
  • FX – predefined task types
  • This_is_Your_Explosion – task name(alphanumeric & any number of underscore)
  • max – each program identifier

Project Manager Tool

Now we have a rule. Next, we need a tool. Because the consistency of the data is key for pipeline automation. As I said in the beginning, No human can remember these rules and execute correctly all the time. Only way to make this work is having a tool. Something like this.

  • The tool hides the rules and the naming convention from artist and allow to browse the project easily.
  • Allows to load/version up their project. When the version is up, it will automatically version up to the latest.
  • Allows to create new task, and convert the current scene as the first version.
  • Allows to add/edit notes.
  • Remembers the history of project file load/save and allow to quickly select from history.

These list is just a start. Since you have a way to browse set the context of task.  You can add more and more features to this tools. For example…

  • The time logging could be integrated into this UI or even automate it by detecting the file being opened.
  • Could have an easy shortcut to open folders for the chosen task.
  • Could display Flow(ShotGrid) notes for the task.
  • and more and more.

Thanks to the fact that most programs are now supporting Python. You can build the interface once and reuse it for many programs. You can see my example tool is working in Maya, Houdini, Nuke even for Photoshop.


Expand The Naming Convention to Renders

After the project file name convention and tool are sorted out, the next stop would be the render output file name.

For render output, we need to extend upon the project file naming convention so we can automatically track where the renders are coming from.

This is an example of render output file path and name convention.


This is what I did.

  • I changed “work” to “render3d” so you can have a render3d folder per episode. With this, you can delete render outputs first after a project is done while keeping project files.
  • You would have multiple outputs from a project file. Usually we call them “pass”. So, I added the pass folder after the task name folder.
  • I used “-” as a separator so I can use “_” in the pass name if I need.
  • Then, we need the version folder since you will likely output an image sequence. It is always a good idea to have only a sequence in a folder.
  • Then, you have the exr sequence file in the version folder. For frame number padding I would recommend to use “.” as a separator than “_”.

NOW here is a little bit controversial part, render elements(AOV). If you are using the multi-channel exr workflow. You wouldn’t need a render element sub folder. I personally am not a big fan of putting all channels in a gigantic exr file.

If you are using the split file workflow, you also need to add a render elements folder. As I mentioned once, it is always better to be consistent. So, I would have the RGB element in its own folder. But, some may opt to leave RGB in the version folder and only have other elements in their own folder.

Then, your file could be something like this.


If you decide to have AOV folders, here is one more thing you might think about.  You can swap the position of the AOV folder and the version folder like this.


This makes deleting unnecessary AOVs easier since all versions for a pass are under a folder and. it is easier for a code to pull all the versions list. But, this also makes it harder to know what is the highest version of all to determine the next version, and deleting certain version becomes more difficult.

OK, now one last thing I need to talk about render output is how to decide the version number. Obviously the simplest method would be to keep versioning up for every render submission.

Another way of versioning is syncing the output version number to the scene file version number. For example, , If your scene version is v008, your render output also becomes v008. It is possible because the render output naming convention has all the items of the project file naming convention. There is no chance that different max files could generate the same render output.

If you do this, you have to version up your scene file to get a new version of renders. This also means you will have skipped versions. That sounds bad. Why would you do this then? Because it allows you to easily track where your renders come from without any extra system. If you automate max file version up after submitting render, you can always go back to the version of max file when you need and get exactly the same render again.

renderStacks to the rescue

Now you need a tool to set the render output path automatically. Yes, right. This is the moment that you need renderStacks. 🙂

In the following picture, you can see I just made a global function and feed it as maxscript token for rednerStacks. Now you never need to type render output path ever. renderStacks will automatically set the render output path every time when you submit or render.

Of course, you can use any other script/tool, too. The point is that you must have a tool to set it.


Now you have a naming convention for project file and render output and have a tool to handle those path. Then, we can say you have a MVP(Minimum Viable Product) pipeline. But, if your workflow requires comps most of the time. Then, you would like to have naming conventions for comp and precomp as a next step.

This was the project file naming convention for max.

Z:\Project\HOUSE\201\work\24-56\FX\This_is_Your_Explosion\max\HOUSE_201_24-56 – FX_This_is_Your_Explosion_v001.max

For 3d projects, it made sense to have lookdev, fx, and animation task types. But, for comp, do you need them? Do you have a comp for fx and a comp for lookdev? Probably not…

Then, what should we do with the task type? We can remove the item from file and path name convention. That means you would need a separate naming convention for comps which means it will cost more to develop and maintain while having more chances to have a bug. As I mentioned a few times, it is always better to be simple and consistent.

Therefore, I would keep the task type. But, I would change the items. We can at least have a “comp” task type. How about the task name? Usually you would have 1 comp per shot. But, you never know if you would need more than 1 comp in the future. What if the director wants to have 3 options! Since we already have it in the naming convention, it is better to keep it consistent and flexible. But, we can have a soft convention to agree to use “main” as a default task name.


Now here is something to think about. How about other support task like precomp or roto? If it is for precomp for the same nuke file. It could be just another “pass” like 3d render. But, if it needs its own nuke file, you have 2 choices. 1) having its own task type 2) using a task name.

If you decide to have its own task type such as “precomp” or “roto”, you will have one more level of flexibility( task name + pass name). It also means precomp or roto will have their own sub folders which means it will be easier to clean up. But, you will have a lot of empty or folders with only one sub folder.

Or, you can just utilize the task name. Just make sure artists use “precomp_” or “roto_” prefix or build a tool that can force it.

Lastly, I would separate the comps from the 3d renders. Something like under “image2d”.  Our final comp/precomp file naming convention will be like this.

Z:\Project\HOUSE\201\image2d\24-56\comp\main\main\v001\HOUSE_201_24-56-comp –mainmain_v001.0000.exr

  • main – is the task type.
  • main – is output name from a comp project file. If you are using Nuke, this would be your Write node name.

Of course, you should never generate this path manually. For local rendering, you would make own render dialog with automatic path update. For network render, you would a code to update Write nodes version to latest before open network render submission dialog.

Happily ever after

After you implement a good naming convention and tools, you can start to take an advantage of the consistent and predictable structure of files. For example, this is the image loader for my project manager. It build the list of all image assets(render3d, comp, precomp)

This is a Nuke Read node updater.

Assets, Caches and Beyond

If you want to go further, you can start to explore a pipeline for asset publishing. I wish continue this tutorial to cover asset publishing. But, unfortunately, everybody works differently, and it is hard to make a universal solution without bloat.

But, I have a few cents that I can share from my experience.

  • Start from the simplest asset. Usually the camera publishing is the best candidate. The data is small, and it is such an essential.
  • The next would be the cache or proxy that you would use most often. If you use Phoenix, that would be a good candidate.
  • The best pipeline is just automating what you have done. Do not try to force what you saw or heard from the internet. Again, each company has own way of working. Do not try to change it. Try to improve it.
  • Don’t try to do too many thing too fast. In terms of pipeline, the stability is more important than features. If artist can’t trust the pipeline, they will try to avoid it and work around it.

OK! That’s it. Now you know where to start to build your awesome pipeline. I think I put enough information in this post. But, if you think you need help or just want to use what I have built. Contact me through LinkedIn message. I’m available for consulting. 🙂

New 3dsMax 2025 Menu System and How to Transfer UI Customization to a New Version

New Menu System

One of the new 3dsMax 2025 features is the completely rewritten new menu system for menus and quad menu. This is a part of the initiative called Upgrade-Safe UI which was introduced in 3dsMax 2020 for the hotkeys first.

For users, the most important and beneficial change is how the customization is stored and loaded.

The legacy UI customization system was the “Save and Load” system. When users customize menu items and save them, the entire menu status is saved in a .mnux file. Then, when users load the .mnux file, the entire menu items will be replaced by the content of the file. This causes the following issues.

  • Dev added a feature XYZ in a new version and added menu items for that. All these newly added items will disappear when users loaded a .mnux file from an older version of max.
  • A user had a plugin ABC and menu items for it when they save the .mnux file. But, the new 3dsMas version doesn’t have the plugin anymore. When users load the ,mnux file, all the menu items for the plugin ABC will remain in the menu and be broken.

To address these problems, the new menu/hotkey system uses a transformation approach. Basically instead of save/load the explicit configuration of the menu, the new system stores only the delta(change) from the default menu/hotkey and applies back the changes and overrides the default status.

This will allow users to keep the changes they made while still receiving updates from the global changes. This also means the menu customization will be portable between versions and machines.

This also means it is very easy to go back to the default menus if you need to by simply choosing the locked “3dsMax Default Menus” configuration. This is the same for hotkeys since they are using the same system. Everybody probably had an experience where you had to jump on other’s max and realized that all the hotkeys and quad menu are heavily customized. Now you can easily revert to Default and back to the custom.

User Settings Folder

The menu file(.mnx) are saved in the “User Settings” folder by default. This folder is in the  “Autodesk” folder in the user folder, not the hidden AppData folder.  C:\Users\[username]\Autodesk\3ds Max 2025\User Settings

You can also set a custom location using ADSK_3DSMAX_USERSETTINGS_DIR env var.


This means that all these settings will survive when you nuke ENU folder to fix issues. Also, you can just copy everything in this folder to another  version or machine to get all the settings in this folder.

Currently the following settings are stored in this folder. Any files in this folder is portable and upgrade safe. When you move version to version. Just copy them to the new version folder.

  • Hotkey Set File(.hsx) – need to load to apply
  • Menu Configuration File(.mnx) – need to load to apply
  • Custom Default File – DefaultParameters.ini
  • MaxToA settings
  • Viewport Settings Preset – High Quality/Standard/Performance are just presets of Per-Viewport Configuration. You can even make your own, and the own preset settings file is stored in this folder as .json file.


Plugins/Script Developers

The old menu system is gone now. So, Maxscript Menu Manager interface(MenuMan) is gone. If your plugin/script/pipeline has been using MenuMan for adding custom menus. You need to update to the new system.

A good news is that now you don’t necessarily need to code to add menus. The application package now support “menu parts” component. I updated my scMakePreview to demonstrate how you can use this for any scripts.

You can download and check the package. But, in short, I modified the menu and saved .mnx with the new Menu Editor. Then, add the .mnx file in the package and added this line.

<ComponentEntry ModuleName=”./Contents/cui/csMakePreview.mnx”/>

The plugin package will replace the built-in Make Preview viewport menu with csMakePreview like this. Pasted-6

To assist this, The “Developer Mode”.has been added to the new Menu Editor. When you switch to this mode, only the base and either the selected preset or an empty preset is loaded(no plug-in and user defined menus)to provide a clean configuration to work with.


How to Upgrade/Transfer All Your Customized UI, Preference, Plugins, Scripts


There are 5 UI items you can customize. Mouse, Toolbar, Menu/QuadMenu, Hotkey, Color.

  • Hotkeys – If you use a newer than 3dsMax 2020.1, just copy files in the User Settings folder and load your Hotkey Set File(.hsx)
  • Menu/QuadMenu – Since the nes system is just introduced(2025), you will get the benefit from 3dsMax 2026. But, if you need to transfer the customization for 3dsMax 2025. Same as Hotkey,  just copy files in the User Settings folder and load your Menu Configuration File(,mnx).
  • Mouse, Toolbar, Color – These are still using the legacy system. I really hope the 3dsMax dev works on the toolbar sooner than later. For these, you need to load the customization files from an older version.

But! Which file is THE file you need to use? Isn’t there a million places that have ui files? Well… Yes and No. First, the answer to the question is \en-US\UI\MaxStartUI.* files under ENU folder.

C:\Users\[username]\AppData\Local\Autodesk\3dsMax\2024 – 64bit\ENU\en-US\UI\MaxStartUI.*

This is the ui files that gets updated when you close 3dsMax when you turn on “Save UI Configuration on Exit” in the Preference, and they are loaded when 3dsMax starts.

Browse to the 3ds Max ENU folder you want to load UI from and load them. MaxStartUI.cuix is for the toolbar, and MaxStartUI.clrx is for the color. For mouse, MaxStartUI.musx is not automatically generated. So, you can save anywhere and load it.


A Friendly Reminder!

Before you transfer any of this UI customization. You need to make sure to install all your plugin/scripts first. For that matter, I already have 3 parts for this. I highly recommend you to read this and try. Since I have implemented this setup, I never ever needed to touch any plugin/scripts install/setup ever again.




!!! Updated to 1.1 If you have downloaded 1.0, please download again !!!

This is a simple script that syncs a camera with an active perspective view. If you want to control a camera view just like perspective view navigation, this is the script for you.

How to use is simple. Select a camera to sync from drop down and turn on Sync. If you turn off the button or close the dialog, the sync will stop.

A few things to remember!

  • It can’t support targeted camera. Use Free camera or turn off “Targeted” for a Physical camera.
  • It controls “fov” parameter. So, as long as the camera has and is set to control with “fov” parameter, it would work. THis also means you must turn on “Specify FOV” for Physical camera.
Download csSyncPersToCam 1.1


Substitute modifier mini tutorial and csStackCache

Substitute modifier is one of the most underrated modifiers in 3dsMax and one of my favorite modifiers. As the name suggests, this modifier replaces the object’s mesh/poly. How to use is very simple. Just apply the modifier, turn on “Pick Scene Object” button and pick an object in the scene to substitute.

You can choose to use the substitute mesh only for viewport or render.

You can also choose to use an object from another max file.

We can think about a few useful situations such as…

  • I already have a big stack and animation started from Box. Now I wanted to start from ChamferBox instead of Box.
  • I can substitute highres objects with low res ones only for viewport to make viewport faster.
  • I can have low res placement holder objects in the scene and substitute with highres objects in another max file.
  • You can have multiple versions of mesh in an object while keeping all the connection to other portions of 3dsMax.

BUT! That’s not all. Substitute modifier has more super powers.

It automatically disables the evaluation of all the modifiers under it

It makes sense since the Substitute modifier provides a mesh from the stack point. Whatever at the below of the stack doesn’t do anything in any way. The best part is that you don’t have to set anything manually. This modifier just does it. Combined with the feature that allow to use Substitute modifier only for viewport display, this provide a great work around to improve the scene performance when you have a lot of hires animated meshes.

For example…

  • if you substitute an animated tree with a static low res tree, this modifier blocks the evaluation of animation.
  • If you have an animated alembic cache object, this modifier will stop loading the alembic file every time when you scrub through. In the following image, I snapshot a frame and used that for display using Substitute modifier. You can see alembic object stopped loading  the cache file.
  • Turn off VRayVolumeGrid preview which will load files and update every frame. Make a preview mesh and use Substitute modifier to display it. This will allow you to directly place vdb without waiting for every singler cache file loading.

It can embed the replacement mesh data in the modifier

This is a really really powerful feature. After you pick an object from the scene, you can delete the object. Then, the modifier will hold the mesh information in itself which essentially act as a cache modifier.

This means that you can collapse the stack while keeping all the history. l Some of you probably have been duplicating objects and collapse in the scene and save a copy in another max file for future use. You don’t need to do that any more. Everything can be just stored in the same scene

one of the benefit of caching a big stack is to improve max file loading time. I want to cover this topic in depth some day. In short, 3dsMax file doesn’t save the result of stack in the .max file. If you make a Box and apply Bend modifier. 3dsMax just stores the class(Box, Bend and its parameters. Then, when the file is loaded, it evaluates all the classes and generates a mesh. This means if you have very big stack or very calculation intensive modifiers. The file opening can take a long time. That’s why some modifiers like Boolean, Conform or Retopology have own caching mechanism. With Substitute modifier, you can cache any objects with modifier in the scene if you want. Obviously, it has a trade off. It will increase the max file size. You gotta pick your poison.

Another benefit is that it can be used as a countermeasure for possible mesh corruption. As a procedural evaluation system, if anything goes wrong in the middle of the stack, the above of the stack would produce an unwanted result. For example, Edit Poly is an awesome and powerful modifier. But, it can be fragile with certain operations. In fact, Edit Poly never stored the result of change in the modifier. It is actually a mini stack in a stack. It stores every operation you did and re-execute then you open the file. So, even tho it is slim, there is a chance that one of hundreds of operations, especially one that removes or adds sub-objects, could go wrong. For that case, you can use Substitute modifier to lock/freeze the status of stack.


So, I made a small script called csStackCache to take advantage of Substitute modifier’s super power. You can find from csTools > csStackCach in the Customize UI dialog.

How to use is simple.

  1. Select objects that you want to cache.
    • All – all geometry objects
    • Selection – Selected objects
    • Selection Set – the chosen selection set
  2. Press “Cache”.
    This script will add a Substitute modifier named “csStackCache” just above of the first viewport enabled modifier. In the following image, It is added under TurboSmooth because it was set to Off in Viewport.

    If you already had “csStackCache”, it will use the position. So, if you need to add “csStackCache” at certain position. Use the “Add Cache” button to add and move around it. Then, Cache them. For example, if you have any animated modifiers, you will need to cache blow the modifiers. If you cache above them, it will freeze animation.
  3. If you want to remove “csStackCache”, select objects in the same way and pres “Remove Cache
You can download csStackCache from here.

BUT! I want really want to set a built-in “Cache” button in this modifier. That will be much faster than my scripted solution. So, please visit here and vote for me!


Thinkbox plugins recompile for 3dsMax 2024

All Thinkbox plugins has been open-sourced. But, it still requires a good amount of effort to update for new SDK changes. I have been try to find a way to recompile this and was fortunate enough to find awesome volunteers.

The effort is still going on. I’ll keep adding as we get more. All the relase from me will be an application package format. You just need to unzip in C:\ProgramData\Autodesk\ApplicationPlugins folder or your own application package folder.


The first one is FrostMX with VRay6 and TP support. Big thanks for Vlado for recompiling! Also, big thanks for Marc Auvigne for testing.


Big thanks for David Baker from for recompiling! Also, big thanks for Marc Auvigne for testing.

Ben Lipman also compiled Krakatoa(without TP support). You can find the download link here.

3dsMax 2024.2 Conform Sample Pack

Here is some of max file you saw in the Conform Sizzle Reel including the tire and track scene.

Download 3dsMax 2024.2 Conform Sample Pack



Greg Glezakos – conform_clock, conform_Tire
Paul Erdtmann – conform_tracks
Logan Foster – conform_zipper
Michael Spaw – conform_scanner
Changsoo Eun – conform_array_rope,conform_Fake_Collision conform_noiseball_animated, conform_proxymity_shader, conform_shrinkwrap_band, conform_missed_verts, conform_volume




There has been many requests for providing a way to adjust clipping plane by numbers.
Your voice was heard. 3dsMax 2024.2 bring MXS exposure for the clipping plane.

vpSetting = NitrousGraphicsManager.GetActiveViewportSetting()
vpSetting.ViewportClippingEnabled = true
vpSetting.ViewportClipNear = 0.05
vpSetting.ViewportClipFar = 0.8

Note: Same as UI, the allowed range of near/far is [- 0.1, 1.1], and the specified value should obey the rule: near < far

Of course, I know there are many who don’t/can’t script. So, I made a script for you which you saw in my video.

Download csSetClippingPlane here!

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.