Here we will add more diﬀerent parameters to our shader and they will be integrated to the Maya interface. This will allow us to have an easy way to modify our shader in Maya.
We can add a new shader to the previous shader loader we created in the previous section:
First, create the shader:
Strings for enum values should not start with a number. So this: "1st value" is not a valid enum value.
You can see that node parameters of diﬀerent types are deﬁned, but only the RGBParam is used.
Now, to add the shader to the loader, you only need to add this code to the previous Loader.cpp ﬁle from the previous section:
You will be able to compile the loader again as described in the previous section, check that Arnold can load the shader correctly, and copy the compiled shader to the correct folder so that Maya can use it. If you do so, you will discover that it is usable but not well integrated in Maya.
To integrate this new shader, we can, as in the ﬁrst section, add information to the metadata ﬁle and create a template script for this shader.
To add the metadata information, you only have to add this to the loader.mtd ﬁle created in the previous section that you placed in this folder: %MTOA_PATH%\shaders\
This describes attributes that will be used for the Maya representation of the parameters as name, shortname, slider limits, descriptions and default values.
The last task to do is to create a Maya template for this shader. This is similar to the one created in the ﬁrst section: self.addControl(parameterName, label="Parameter Label"). But adding the rest of the controls. The correct control for each attribute will be created automatically.
Create an aiParametersShaderTemplate.py ﬁle in %MTOA_PATH%\scripts\mtoa\ui\ae\ or in any folder that is deﬁnded in %MTOA_TEMPLATES_PATH%
When you use the ParametersShader in Maya, you will be able to see this Attribute Editor for it.
Figure 4: ParametersShader Template
Now you will be able to conﬁgure your shader's input parameters from Maya.
Maya automatically tries to optimize the layout space, for example, if in the previous code you change from this:
You will see this result:
Figure 5: Optimized Template
To avoid this, we can use this code instead:
And you will get this result:
Figure 6: Optimized Template
Sometimes we may need a certain action to be performed everytime an attribute is changed. For example to evaluate that the introduced value is correct. Let's imagine we require that the value of the uinteger attribute is always greater or equal to the integer attribute. We can try to achieve thit with the following code.
Now everytime that that the integer attribute is updated, if it has a value greater that the uinteger value, this will be increased to be equals to that value. But, of course, if you decrease the uinteger parameter, this could be lower than the integer one. To deal also with this case we can easily write this code:
Sometimes some parameters does not have any meaning depending on other attributes values. For example, let's imagine that the float attribute only makes sense when the bool attribute is true. We can make this clear for the user if disabling the float attribute when bool is false. To do this, ﬁrst we can deﬁne a hangeCommand method as in the previous section, and use there the arnoldDimControlIfFalse method to disable the attribute. Here is an example:
If we want the opposite, making the float attribute to be enabled only when bool if false, you can use aeUtils.arnoldDimControlIfTrue instead of aeUtils.arnoldDimControlIfFalse. But in some cases the condition to enable or dissable an attribute could be more complex. For example we may enable the float value only in the case that the red component of color is greater than 0. You can write a code like this for that case:
MtoA will automatically create a control for the attributes based on its type, but sometimes you may need more ﬂexibility and create a custom control for a certain attribute. For example, let's imagine that the string attribute in the previous example is used to point to a ﬁle. Then you may want a control with a button that shows a ﬁle explorer so you can enter the ﬁle name in a more intuitive way. Here is an example to get that behavior:
Here we will summarize all the previously used template methods and add some new ones:
As previously seen, this command creates a Swatch in the Attribute Editor that shows a preview of the Shader.
Begins and ends a Vertical Scroll Layout where you can place sections and attributes.
Begins and ends a Layout. You can give it a name and deﬁne if it will be collapsed or not by default.
self.beginLayout("Section Name", collapse=False)
Creates a control for a shader attribute. It automatically creates the correct control depending on the type of attribute. You can deﬁne alabel and a changeCommand.
self.addControl("attrname", label="My Attr", changeCommand=self.changeAttr])
Creates a custom control for a shader attribute.
self.addCustom(attrName, newMethod, replaceMethod)
Adds a separator in the layout.
Stops and starts again the layout space optimization.
Creates a section that will allow you to connect a bump normal mapping to the shader.
All extra attributes will be grouped in an ”Extra Controls” section.
Creates a ”Type” scroll list where you can change the shader type of the node.
Creates the ”Node Behavior” section in the shader template.