Adding Parameter Definitions


Adding parameter definitions to a ShaderParamDefContainer or ShaderParamDefContainer is the similar for all parameter data types: for array parameters, you use the ShaderParamDefContainer.AddArrayParamDef or ShaderParamDefContainer::AddArrayParamDefmethod, and for everything else you use the ShaderParamDefContainer.AddParamDef or ShaderParamDefContainer::AddParamDef method.

These methods allow you to specify the name and data type, and requires that you pass in a special object that further defines the new parameter definition: ShaderParamDefOptions or ShaderParamDefOptions. This object allows you to specify the parameter definition's display name, its capabilities (texturable, animatable, inspectable), what default value to use, the valid value range, etc. To create an instance, you can call the XSIFactory.CreateShaderParamDefOptions or XSIFactory::CreateShaderParamDefOptions method and set any values on it before you call the Add method for the parameter definition.

You can reuse the same options over again, only changing what you need before you call the Add methods, if necessary. For example, if you are creating only texturable parameters and don't need to specify a display name, default values, or a value range, you can use the same object in each call to the Add methods. You can also modify one or more options and keep the rest of the options, or get a new instance of the object to reset the values. The ShaderParamDefOptions or ShaderParamDefOptions is also instrumental in applying filters for reference and property look-up data types, and for creating custom parameter.

The principle behind adding the simple parameter definition data types applies to the more complex types, such as structures, property look-ups, and references; however there are also a few extra measures to take which are explained in the sections below:

To add simple parameter definitions

Before calling the ShaderParamDefContainer.AddParamDef or ShaderParamDefContainer::AddParamDef method, set up the shader parameter definition options. This example uses the ShaderParamDefOptions.SetLongName or ShaderParamDefOptions::SetLongName method to set the name that appears in the UI, and the ShaderParamDefOptions.SetTexturable or ShaderParamDefOptions::SetTexturable method to allow this parameter to be connected in the render tree.

// Set up an RGBA color data type
var oPDefOptions = XSIFactory.CreateShaderParamDefOptions();
oPDefOptions.SetLongName("sweet");		// this becomes the port name in the UI
oPDefOptions.SetTexturable(true);		// display as a node in render tree

// You need to set up the options before you can add the param def
var oInputParamsContainer = oShaderDef.InputParamDefs;
oInputParamsContainer.AddParamDef("simple", siShaderDataTypeColor4, oPDefOptions);

// Change only the UI name, and keep the rest of the settings
oInputParamsContainer.AddParamDef("simple2", siShaderDataTypeColor4, oPDefOptions)

// A similar parameter, this time appearing only as a parameter on the PPGLayout
oPDefOptions.SetTexturable(false);		// display in associated property page only
oInputParamsContainer.AddParamDef("torque", siShaderDataTypeScalar, oPDefOptions);

# etc.

For information on how to add more complex types, such as texture space ID or reference controls, see Refining UI Controls for Parameter Definitions.

To add array parameter definitions

Adding array parmeter definitions is just like adding the single version of the same data object. The ShaderParamDefContainer.AddArrayParamDef or ShaderParamDefContainer::AddArrayParamDefmethod returns a ShaderArrayParamDef or ShaderArrayParamDef object.

// Add an array of gradients
oParamDefOptions = XSIFactory.CreateShaderParamDefOptions();
oParamDefOptions.SetTexturable(true);// connectable port
oInputParams.AddArrayParamDef("train", siShaderDataTypeGradient, oParamDefOptions);

If you leave the code as is, your shader will initialize with an empty array, like this:

However you can refine your array parameter definition in several ways:

To add a structure parameter definition

When you call the Add method you need to grab the return value, which is a ShaderStructParamDef or ShaderStructParamDef object. This specialized parameter definition implements the ShaderStructParamDef.SubParamDefs or ShaderStructParamDef::GetSubParamDefs member which provides access to the ShaderParamDefContainer or ShaderParamDefContainer. From this container you can add sub-parmeter definitions using the Add methods.

// This example of a struct builds the "si_default" input structure for the 
// Bionic Volume (Fast Volume Effects) shader implemented as a plug-in
var oParamDefOpts = XSIFactory.CreateShaderParamDefOptions();

// Add the structure type parameter to the shader definition
var oInParamDefs = oShaderDef.InputParamDefs;
var oStructParamDef = oInParamDefs.AddParamDef("si_default", siShaderDataTypeStructure, oParamDefOpts);

// Get the structure parameter container and start adding sub-parameter definitions
var oSubParamDefs = oStructParamDef.SubParamDefs;
oParamDefOpts = XSIFactory.CreateShaderParamDefOptions();

// "start"
oSubParamDefs.AddParamDef("start", siShaderDataTypeScalar, oParamDefOpts);

// "stop"
oSubParamDefs.AddParamDef("stop", siShaderDataTypeScalar, oParamDefOpts);

// "rate"
oSubParamDefs.AddParamDef("rate", siShaderDataTypeScalar, oParamDefOpts);

// "transmit"
oSubParamDefs.AddParamDef("transmit", siShaderDataTypeColor4, oParamDefOpts);

// "lightrays"
oSubParamDefs.AddParamDef("lightrays", siShaderDataTypeBoolean, oParamDefOpts);

To add a property look-up parameter definition (CAV, texture map, normal, etc.)

Property type parameter definitions provide a property look-up widget for weight maps, texture maps, normals, color-at-vertices, etc. You can apply a filter to get widgets for specific properties.

// Apply the Color-At-Vertices filter to the parameter definition options
var oParamDefOptions = XSIFactory.CreateShaderParamDefOptions();
oParamDefOptions.SetTexturable(false);								// PPGLayout only
oParamDefOptions.SetAttribute(siPropertyFilterAttribute, siCAVPropertyFilter);

// Add the "VertexColor" parameter definition to the input list as a property look-up type
var oInputParams = oShaderDef.InputParamDefs;
oInputParams.AddParamDef("VertexColor", siShaderDataTypeProperty, oParamDefOptions);

To add a reference parameter definition

Reference type parameter definitions provide a widget for the user to pick an element in the scene. You can apply a filter to limit the kind of items the user can pick from.

// Apply the Cameras filter to the parameter definition options to make sure 
// that the user can only pick cameras
var oParamDefOptions = XSIFactory.CreateShaderParamDefOptions();
oParamDefOptions.SetTexturable(false);									// PPGLayout only
oParamDefOptions.SetAttribute(siReferenceFilterAttribute, siCameraReferenceFilter);

// Add the reference parameter to the list of input parameter definitions
var oInputParams = oShaderDef.InputParamDefs;
oInputParams.AddParamDef("reference", siShaderDataTypeReference, oParamDefOptions);

Bonus: To add an output parameter definition for a lightmap (custom)

Shader definitions of the mental ray Lightmap Shader family always define the output parameter as a custom type, and then set a special attribute on the parameter definition options to indicate that it is a lightmap:

// Set the custom attribute to mrLmap on the options before adding them
var oParamDefOpts = XSIFactory.CreateShaderParamDefOptions();
oParamDefOpts.SetAttribute(siCustomTypeNameAttribute, siMentalRayLightmapPortType);

// Then add the new method to the output parameters container
var oOutParamDefs = oShaderDef.OutputParamDefs;
oOutParamDefs.AddParamDef("out", siShaderDataTypeCustom, oParamDefOpts);