![]()
Implementing a hardware shading node plug-in
There are two interfaces in
MPxHwShaderNodethat can be implemented for renderer’s hardware shading node plug-ins. Although the two interfaces are similar when comparing parameters, the ways they are called are quite different.The bind/geometry/unbind interface
Implementing the
bind(),geometry()andunbind()methods allows a hardware shading node plug-in to render in the Maya scene view. The purpose of the three methods are:
- bind is used to setup OpenGL state and resources.
- geometry is used to render the shader effect.
- unbind is used to restore OpenGL state and clean up resources.
Only Mesh shapes are supported in this mode and the following steps are used to draw:
- Maya visits each Directed Acyclic Graph (DAG) node collecting draw requests.
- Draw requests are sorted into opaque and transparent queues.
- Maya performs the opaque draws without sorting.
- Maya depth sorts the transparent queue and performs the transparent draws.
The response to Maya’s requests for draw information is the following:
- Mesh shape receives the draw request.
- Shape checks to see if the material is a hardware shader.
- If it is a hardware shader node plug-in, the geometry is bundled and passed to the virtuals of the node.
- The hardware shader node plug-in uses the information passed to it to decide how to render to the screen.
The order in which the interface virtuals are called is the following:
The result of this calling pattern is that the OpenGL state can be set in the
bind()method, used in thegeometry()call and then restored inunbind().A M3dView parameter is passed to the methods of this interface. This parameter must be used to set the graphics context that will be used for drawing. Bracketing the functionality of the virtuals in this interface with
beginGL()andendGL()method calls is required. For example:MStatus hwShader::bind( const MDrawRequest& request, M3dView& view ) { view.beginGL(); // Operations ... view.endGL(); }Failing to call these methods can result in program corruption.
The glBind/glGeometry/glUnbind interface
Implementing the
glBind(),glGeometry()andglUnbind()methods allows a hardware shading node plug-in to render in the Maya scene view. The purpose of the three methods are:
- glBind is used to set up plug-in state and resources.
- glGeometry is used to set OpenGL state, render the shader effect and restore OpenGL state.
- glUnbind is used to restore plug-in state and resources.
In this interface, the order that the virtuals are called is the following:
for every pass // a refresh may have more than one pass { for every object { if glBind() has not been called for this refresh glBind(...) glGeometry(...) } } for every object glUnbind(...)There are several implications that must be considered because of the change in calling order. With this interface, the OpenGL state must now be set in
glGeometry()rather thanglBind(). NowglBind()will only be used for loading resources and processing any required attributes that will be used inglGeometry().Unlike the previous interface, graphics context is already set and no calls to
beginGL()orendGL()are required.Controlling what information is passed to geometry/glGeometry
The
geometry()andglGeometry()methods have very large parameter lists including a mixture of mandatory and optional data that describes the vertices and faces the shader needs to render the current geometry. The following methods control which optional data should be passed to the shader:virtual int normalsPerVertex(); virtual int colorsPerVertex(); virtual int getColorSetNames(MStringArray& names); virtual int texCoordsPerVertex(); virtual int getTexCoordSetNames(MStringArray& names); virtual bool provideVertexIDs();It is important to note that requesting information that is not available will cause NULLs to be passed to the shader. Hardware shader plug-in nodes should test parameter information against NULL to ensure that data is valid.
Transparency and hardware shader plug-in nodes
Maya depth sorts draw information when transparency is present in a shader. If the hardware shader plug-in node does not support transparency, then the following virtual can be implemented to return
falsein order to gain shading performance.Indexing and Sparse Arrays with the geometry() and glGeometry() methods
Data is passed to these methods using an indexing mechanism. These methods are:
virtual MStatus geometry( const MDrawRequest& request, M3dView& view, int prim, unsigned int writable, int indexCount, const unsigned int * indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays); virtual MStatus glGeometry( const MDagPath& shapePath, int glPrim, unsigned int writeMask, int indexCount, const unsigned int* indexArray, int vertexCount, const int * vertexIDs, const float * vertexArray, int normalCount, const float ** normalArrays, int colorCount, const float ** colorArrays, int texCoordCount, const float ** texCoordArrays);The parameter used for indexing is
indexCount,which contains the length of the arrayindexArray. The indices contained withinindexArrayare used to access corresponding elements in the other arrays such as vertex positions, colors and normals.There are several parameters passed to the geometry methods which are arrays of arrays. These are the pointer to a pointer parameters. It is possible for these arrays to be sparse. The sparseness can occur if one of the information requesting methods asks for more information than actually exists. For example, the
getTexCoordSetNames()method can request 3 UV sets, but only the first and third exist. In this situation, the second position with the array of arrays will be NULL. As a result, it is important to use NULL checks to ensure the data is valid.Blind Data
Using baked vertex mesh blind data for the hardware shader node plug-in can be a very useful technique for rendering. This is possible for both versions of the geometry methods. The hardware shader node plug-in must implement the provideVertexIDs() to return
true. When this is done, the vertexIDs array will contain the requested information and vertexCount will contain the length of the array. If using a MDrawRequest, the mesh can be accessed using:In the case of the gl version of the interface, the mesh is available from the shapePath parameter. Using the shape and the vertex IDs together lets you access vertex blind data through the
MFnMeshclass.Integration with other parts of Maya
You can strongly integrate the hardware shader node plug-in with other parts of Maya using the
MPxHwShaderNodeclass. See the next section.Software rendering and the Shader Swatch
You can implement a hardware shader node plug-in in a way that produces a reasonable output for software rendering and the Shader Swatch in the Attribute Editor. The basis of the functionality is implementing the
compute()method to affect theoutColorattribute. If this is done, the software rendering and Shader Swatches will no longer be default black.Alternatively, a hardware shader node plug-in can also choose to implement a specific virtual for drawing just the Shader Swatch. This method is:
The following swatch classification string is required by this functionality:
This string is passed to Maya when the plug-in calls
MFnPlugin::registerNode().The UV Texture Editor
There are a number of methods in
MPxHwShaderNodethat help to integrate hardware shader node plug-ins into the UV Texture Editor. These methods are:virtual MStatus getAvailableImages( const MString& uvSetName, MStringArray& imageNames); virtual MStatus renderImage( const MString& imageName, const float region[2][2], int& imageWidth, int& imageHeight);The first method getAvailableImages() is used to provide a list of UV channels that will be made available in the UV Texture Editor. The second method renderImage() is invoked when a channel is selected in the UV Texture Editor. It is then up to this routine to draw the image as requested.
If a hardware shader node plug-in uses standard Maya textures, then there is no need to implement these virtuals. The standard Maya textures will available in the Texture Editor.
Icons for the Hypershade window
You can specify an icon for a hardware shader plug-in node that will then be displayed in the Hypershade window. If no icon is specified, then a default blank icon is shown. To specify an icon for a hardware shader plug-in node, do the following:
- Create an xpm icon file named
render_nodeName.xpm. For example,render_hwPhongShader.xpm.- Place the icon in a location (path) defined by the environment variable
XBMLANGPATH. (Alternatively, modifyXBMLANGPATHso that the icon can be found.)Drag and Drop Behavior
You can implement drag and drop behavior on a hardware shade node using the
MPxDragAndDropBehaviorclass. TheMPxDragAndDropBehaviorclass provides a number of virtuals that are implemented for supporting the drag and dropping of nodes in the Hypershade menu. Consult thehwPhongShaderBehavior.cppexample for how to implement drag and drop behavior.