Overriding shader parameters in procedurals

Procedurals (aka standins) don’t expose the parameters of objects and shaders inside the procedural.

For example, you cannot override shader parameters like standard.Kd (diffuse color) or standard.emission (emission scale) by setting those parameters on a procedural node.

But what you can do is use “user data parameters”. Inside the procedural, use user data shaders to set shader parameters, but don’t define the user data parameters on the shape.

For example, if I wanted to be able to override the emission scale, then I would set up a shader like this:


A userDataFloat shader sets the Emission. The important thing is that the custom attribute emission_scale is not defined on the shape, so the default value is used instead.

By doing that, I can put an emission_scale attribute on the procedural node, and the aiUserDataFloat shader picks up that value.


In the above example, I’ve added a mtoa_constant_emission_scale attribute to the standinShape, and that allows me to set the Emission for that specific standin.

In Arnold scene source (ASS) format, I have this in my main scene file:

 name ArnoldStandIn1Shape
 dso "standin_torus_w_emission.ass"
 declare emission_scale constant FLOAT
 emission_scale 0.649999976

And in the ASS file loaded by the procedural, I have this:

 name pTorusShape1
 shader "someshader"

 name someshader
 emission aiUserDataFloat1
 # NO user data declared here

 name aiUserDataFloat1
 floatAttrName "emission_scale"
 defaultValue 0.100000001


Force Translate Shading Engines?

You may have noticed the Force Translate Shading Engine option in the export dialog (or in the Feature Overrides section of the Render Settings).

Force Translate Shading Engines forces MtoA to export shape nodes with a shader link, like this:

 shader "aiStandard1SG"
 declare mtoa_shading_groups constant ARRAY NODE
 mtoa_shading_groups "aiStandard1SG"

where “aiStandard1SG” is the name of a MayaShadingEngine shader node.

This allows you to keep your shapes and shaders in separate ASS files. For example, you could have one standin that loads the shapes, and a second standin that loads the shaders. As long as the shape nodes include links to the shaders, Arnold will resolve the links and render the shapes with the right shaders.

Setting the procedural’s load_at_init parameter to true would also fix this.

There’s an Arnold error that recommends setting the load_at_init parameter, but people don’t always know where to find that in their favorite Arnold plugin.

ERROR| [proc] c4d|Arnold_Procedural: bounds supplied to procedural node are not large enough to contain the actual underlying geometry.
Replace given bounds: (-1, -1, -1) X (1, 1, 1), with: (-9.4028616, -9.43616867, -9.21633244) X (9.3304739, 9.43616867, 9.21633244).
Setting the procedural's load_at_init parameter to true would also fix this.

The load_at_init parameter controls whether the procedural (standin) is loaded during scene intialization (before rendering starts), or during rendering (when a ray hits the procedural bounding box).

By default, load_at_init is false, which means that procedural loading is deferred until render time.

And so, in MtoA, C4DtoA, and SItoA, the load_at_init parameter is exposed as Defer Standin Load, which is enabled by default. In HtoA, you have a Load At Init parameter on for the Arnold Procedural node.

WARNING : [ass] node name already in use

Shader nodes must have unique names.

So if you’re using standins, each standin ASS file has to have unique shader node names. Otherwise you’ll get unexpected results when you render, like all standins having the same shading, or some “flickering” in animation if the order of standin loading changes.

In the Arnold log, look for “node name already in use” warnings:

WARNING | [ass] standin_01.ass line 50: node name "aiStandard1SG" already in use
WARNING | [ass] standin_01.ass line 58: node name "aiStandard1" already in use
WARNING | [ass] standin_01.ass line 118: node name "file1" already in use
WARNING | [ass] standin_01.ass line 147: node name "aiNoise1" already in use


If each standin should look different, you need to have unique shader names in each ASS file. If you’re using MtoA, that includes the name of the SG node (for example, aiStandard1SG).

[Arnold] Standins and the ASS file cache

Did you ever notice the ASS file cache stats in the Arnold log? It’s a breakdown of how many unique ASS files were loaded, and how many were reused:

03:11:33 8868MB | -----------------------------------------------------------------------------------------
03:11:33 8868MB | .ass file cache:
03:11:33 8868MB | unique (loaded from disk)     10 ( 1.00%)
03:11:33 8868MB | reused (found in cache)      990 ( 99.00%)
03:11:33 8868MB | total referenced .ass files 1000 (100.00%)
03:11:33 8868MB | -----------------------------------------------------------------------------------------

Roughly speaking, this caching of standins means that if you have 100 standins that all load the same ASS file, you’ll get one set of geometry and 99 instances of that geometry. That saves memory and I/O time and is just more efficient.

More here…

[MtoA] Using standins to load animation sequences

To load an animated sequence into a standin:

  • In the Attribute editor for the StandInShape, under File/Frame, your Path should be something like example.####.ass (you must use four # symbols for the frame number pattern)
  • Enable Use Frame Extension
  • In the Frame box, type “= frame” without the quotation marks, and press ENTER. That creates an expression that uses the current frame number to specify which ASS file to load.