Share

Custom UI for Third Party Shaders - Arnold for 3ds Max

The MAXtoA Plugin and Shaders

The MAXtoA plugin is responsible for the integration of Arnold shaders in 3ds Max. This integration allows all built-in shaders as well as third party shaders to be integrated into 3ds Max and used in the course of rendering scenes.

Arnold's built-in plugins and shaders are automatically loaded by MAXtoA. Third-party shaders must be placed into the MAXtoA directory or a directory in the plugin path (as set in the Render dialog) to be loaded. However, it is the presence of the MAXtoA plugin that makes this integration possible.

MAXtoA is responsible for mapping Arnold shader nodes and building the matching 3ds Max materials and textures, maintain their integrity, and build a user interface so that 3ds Max users can interact with the Arnold shaders.

This user interface integration is automatic, and the shader developer does not have to do anything. Arnold shaders will be automatically loaded in 3ds Max and visible in the Material editor when Arnold is set as the ActiveShade or Production renderer.

Arnold shaders in the Material Editor

From that moment, shaders can be created by selecting them in the tree view of the material editor and dragging and dropping the node on the canvas or double-clicking the name, like any other 3ds Max material or map.

  • Any shader returning a CLOSURE will show up in 3ds Max as a Material.
  • Any shader returning any other type will show up in 3ds Max as a Map.

Shaders are located under the Arnold category of the Map/Material Browser. They are categorized according to metadata (more on this below).

If a shader lacks categorization, it will be categorized under the name of the DLL it is loaded from, the "OSL" category if it is an OSL shader, or the "Built-in" category if it is built-into the Arnold core.

The shader will display its attributes as defined by the shader developer. Double-clicking the shader (or in 3ds Max terms, the Material or Map) will trigger the user interface of the shader to be created and displayed in the right pane of the material editor.

UI Customization overview

Shader developers can, if they wish, customize the user interface of their shader. There are two ways:

  • Using metadata
  • Using Qt ".ui" files.

Metadata allows renaming, grouping, and reordering of the controls, but does otherwise not affect the layout, whereas using .ui files allows designing a fairly complex custom user interface for the shader.

Automatic User Interface

MAXtoA provides the shader developer an automatic mechanism that creates the user interface for any shader. The developer has nothing to do but to make their shader available to 3ds Max.

For the sake of documentation, a simple shader with support files is provided. The Kick utility can be used to list the shader attributes. The command 'Kick -info simple' will generate this output:

 Type           Name                              Default  
 ------------  --------------------------------  --------------------------------  
 INT           integer                           -3  
 UINT          unsigned_int                      4  
 FLOAT         float                             1.92  
 BOOL          boolean                           false  
 RGB           color                             0.7, 0.7, 0.7  
 RGBA          acolor                            1, 0, 0, 1  
 POINT         point                             1, 2, 3  
 POINT2        point2                            5, 6  
 ENUM          elements                          space 

The generated UI will look something like this when no custom UI is defined. As you can see - the parameter names are used as a label, and each parameter that is linkable is a button at the end used to select an input.

A second rollup is created which contains only the parameter mapping and a control to enable/disable the connection.

The generated user interface is clean and can be used pretty much as-is. Note that the parameter names are 'beautified'; parameter names that contain underscores are split with spaces, and the first letter of every word is capitalized, so;

unsigned_int -> Unsigned Int

Customizing User Interface

To be able to build a custom user interface, we need to understand the parameter mapping between Arnold and 3ds Max and know which control type to use.

For every Arnold shader, we generate some 3ds Max (1 or 3) parameters depending on if the parameter is linkable or not.

As you can see from the following - parameter unsigned_int has two controls in the parameter rollup - the number, and a slot to put a map into. A third one (to enable the map) can be found on the Maps rollout.

So for our "simple" shaders parameter named unsigned_int, MAXtoA will generate the parameters unsigned_int, unsigned_int.shader and unsigned_int.connected. Note that parameter names are case sensitive.

When MAXtoA generates the UI, it will create two rollups (Parameters and Maps) and layout the various controls in a grid layout.

Parameters type to control type is done automatically in this case.

Metadata UI customization

The first level of customization of the shader UI can be achieved using a metadata file. This file must have the same base name as the shader DLL. So in our example, we have a sampleShader.DLL and a sampleShader.mtd file.

Attribute Name

The first customization we can do and the most obvious is to provide a user-friendly name for parameters. This can be achieved by adding a few lines for every attribute of the shader. Here is our shader UI with friendly names.

Through attribute parameters, users can control numeric ranges, add tooltips, etc.


  [node simple]   
  ...  
  [attr unsigned_int]  
  max.label STRING "Unsigned Integer"  
  desc STRING "This is the UNSIGNED INTEGER tooltip"  
  min INT 0  
  max INT 6 

Shader Parameter Ordering

Another way to customize the shader UI is to provide parameter ordering. This needs to be done at the [node] level.

   [node simple]  
  max.order STRING "boolean integer unsigned_int color acolor string" 

Parameters that are not in the list are added at the end. Parameter names that do not exist are ignored.

Rollup Generation

For shaders with a large number of parameters, the user can specify grouping through the folder parameter.

  [node simple]  
  max.parm.folder.folder1 STRING "Rollup1;2;Rollup2;3" 

Note that when specifying folder info - only the parameter count specified will be shown. Better be safe and add a third rollup that will pickup the remaining parameters.

Custom UI Through Qt .UI Files

Custom UI is a mechanism that allows the shader designer to completely design the UI to be used to manipulate the shader parameters.

UI files can be edited using Qt Designer, which can be freely downloaded, and the file format is described here (http://doc.qt.io/qt-4.8/designer-ui-file-format.html).

MAXtoA uses the Qt widget name to map the UI controls to the MAXtoA parameters as found when inspecting the shader DLL. The location of the UI files is relative to the location of plugins being loaded.

So for any shader, a user can create a subdirectory where they will save their UI files. Through metadata specifications, MAXtoA will be able to locate and load the UI files and use them to build a custom user interface. The UI files location is as follow:

<shader-location>/MAXtoA_ui/<Shader-Name>/<ui-files>

For example the standard_surface shader UI files are located in:

<MAXtoA dir>/MAXtoA_ui/standard_surface

In our current distribution, you can find seven UI files: basic.ui, coating.ui, emission.ui, special.ui, specular.ui, sss.ui and transparent.ui in the MAXtoA_ui/standard_surface directory. The metadata file allows us to describe what we want to do for the UI for the standard_surface shader, which is as follows:

Mapping Controls

To achieve this, the developer needs to know which controls can be used to edit which type of parameter. Note that max.parm.folder.folder1 and custom UI are incompatible. Parameter types need to be associated correctly to control types in the .ui file. Here is a list of Arnolds parameter types and the best match control to use.

Arnold Control
INT, UNIT, BYTE MaxSDK::QMaxSpinBox
BOOLEAN QCheckbox
ENUM QComboBox
FLOAT MaxSDK::QMaxDoubleSpinBox

use MaxSDK::QMaxWorldSpinBox if units are required
Bitmap QPushButton
Shader QPushButton
String QEditField
POINT, VECTOR MaxSDK::QMaxPoint2Spinner
POINT2 MaxSDK::QMaxPoint2Spinner
POINT3 MaxSDK::QMaxPoint3Spinner
MATRIX MaxSDK::QMaxMatrix3Spinner
RGB, RGBA MaxSDK::QMaxColorSwatch

There are a few ways to create a 3ds Max control, but the easiest (besides editing the UI file by hand) is to use Qt Designer and follow this procedure:

  1. Drag-and-drop the appropriate widget type into a new form of type widget.
  2. For controls that are not standard to Qt, drag and drop a control "widget".
  3. Using the newly created widget, select from its contextual menu "Promote To...".
  4. Select the appropriate base class (see list above).
  5. Input the appropriate max class name (from list above).
  6. Let the system generate a header file and click Add.
  7. Press promote.

In general, building a custom UI is simple - but there are a few rules that need to be followed:

  • Do not make the rollup wider than 300 pixels.
  • Do not set a hardcoded size for the widgets but instead, once all widgets are laid on the parent widget, create a grid layout that will manage the size of the child widgets. This gives the best performance, specifically for HDPI display.

Parameter Name Convention

As mentioned previously, for every Arnold parameter, MAXtoA will generate 1 or 3 parameters, depending on if it is connectable or not. And the ".connected" and ".shader" parameter automatically gets added to the Maps rollout.

But if one wants these to show up also on the main pages of the UI (e.g. for small map buttons etc.), the way to add these parameters to the custom UI is to use the proper control and name the widget with the parameter name.

So for unsigned_int.connected, the user should create a checkbox control and name it accordingly. Unfortunately, Qt Designer does not allow period '.' characters to be used as widget names. To solve this, MAXtoA will understand the parameter name unsigned_int__dot__connected and programmatically automatically replace the "dot" with "."

In order for the tooltip to function for a custom UI label, the user must name the label widget with the parameter name followed by _label. For example for the parameter count, the label widget should be named count_label.

MAXtoA Supported Metadata Parameters

Metadata files follow Arnold's metadata specification. See Metadata Files. Note: Documentation specifies "As a convention, we are using metadata names starting with "maya." for Maya specific metadata, and "xsi." for XSI specific metadata. There are some other conventions for standard metadata elements that would be published on a separate document."

MAXtoA supports a number of metadata tokens. For node sections [node shader-name]

max.hidden bool The shader will not be visible in max
max.help_url string A help link
max.category string The category
max.label string The label
max.parm.folder.folder[0..9] string For auto-UI mechanism

Describes the rollup names and the number of parameters

Ex: max.parm.folder.folder1 STRING "Diffuse;6;Specular;9"
max.order[0..9] string For auto-UI mechanism

Describes the parameter order. You can extend the parameters list by using max.order[1...9]

Node example:

   # comment 

   [node standard] 

   max.category STRING "Shading" 

   max.parm.folder.folder1 STRING "Diffuse;8;Specular;10" 

   max.order STRING "folder1 Kd_color Kd direct_diffuse " 

   max.order2 STRING "Ks_color Ks direct_specular indirect_specular" 

For attributes sections [Attr attribute-name]

max.type string
max.label string User parameter name
max.disable_when string Disable control when... (need explanation)
min int Range minimum
max int Range max
desc string Description (tooltip)
linkable bool Define if the parameter can be connected to a shader output

Other attributes can be used in the case of a custom user interface.

Note attribute

max.rollup string Describes the rollup custom UI file names

Ex: max.rollup STRING "diffuse;specular"

In this case, there will be a diffuse.ui and a specular.ui files in the MAXtoA_ui/ directory. That directory relative path is the same as the shader's DLL

Example:

   max.rollup STRING "diffuse;specular;reflection;refraction;sss;emission;aov" 

   [Attr rollup-<ui-name>] 
max.label string Rollup user title

Example:

   [attr rollup-diffuse] 

   max.label STRING "Diffuse" 

Was this information helpful?