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 a property look-up parameter definition (CAV, texture map, normal, etc.)
Bonus: To add an output parameter definition for a lightmap (custom)
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 oPDefOptions.SetLongName("salty"); 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 oPDefOptions.SetInspectable(true); 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:
You can populate the array with a specific ShaderArrayParamDef.ItemInitialCount or ShaderArrayParamDef::PutItemInitialCountset to specific ShaderArrayParamDef.ItemInitialValues or ShaderArrayParamDef::GetItemInitialValues.
The name of each item is by default Item, but you can ShaderArrayParamDef.ItemName or ShaderArrayParamDef::PutItemName.
You can get a reference to the ShaderArrayParamDef.ItemDef or ShaderArrayParamDef::GetItemDef to refine it using specific members. For example, in the case of an array of structs, you need to add a number of sub-definitions to the struct, which you can do through the underlying ShaderStructParamDef or ShaderStructParamDef object.
You can ShaderArrayParamDef.StaticArray or ShaderArrayParamDef::PutStaticArray, which prevents users from adding or removing items. In the property page, the Add and Clear buttons are disabled.
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(); oParamDefOpts.SetTexturable(false); // 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" oParamDefOpts.SetTexturable(false); oParamDefOpts.SetDefaultValue(5.0); oSubParamDefs.AddParamDef("start", siShaderDataTypeScalar, oParamDefOpts); // "stop" oParamDefOpts.SetDefaultValue(100.0); oSubParamDefs.AddParamDef("stop", siShaderDataTypeScalar, oParamDefOpts); // "rate" oParamDefOpts.SetDefaultValue(1.0); oSubParamDefs.AddParamDef("rate", siShaderDataTypeScalar, oParamDefOpts); // "transmit" oParamDefOpts.SetDefaultValue(0.5); oSubParamDefs.AddParamDef("transmit", siShaderDataTypeColor4, oParamDefOpts); // "lightrays" oParamDefOpts.SetDefaultValue(false); 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.SetInspectable(true); 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);