Autodesk Maya 2014
UI Drawing enhancements
Shader Override Enhancements
- There is now a new type of shader override (MPxShadingNodeOverride) based on shader fragments. This new system is a direct exposure of the internal
system Maya uses to dynamically build effects for its shading networks. MPxShadingNodeOverride differs from the pre-existing MPxShaderOverride in that implementations of MPxShaderOverride are required to produce the whole shading effect for a shading network (including
lighting), while MPxShadingNodeOverride is only required to produce a small fragment for an individual node within the network.
- Implementations of MPxShadingNodeOverride define a shader fragment or graph of shader fragments to be used to draw a specific
node in Viewport 2.0. This fragment or fragment graph is then connected to the fragments
for the other nodes in the shading network (both those defined internally and by other
plug-ins). The final composite fragment graph is then compiled to a shading effect
and used to draw the objects associated with the shading network for which it was
- Shading fragments and fragment graphs are managed by the new MFragmentManager class. This class allows plug-ins to define new fragments for both GL and DX using
XML to define the structure, parameters and source code of the fragment. MFragmentManager can also be used to query the XML definitions of Maya internal fragments in order
to get examples of how to write new fragments that integrate well with the Maya fragment-based
- A subclass of MPxShadingNodeOverride, called MPxSurfaceShadingNodeOverride, has also been introduced. This class provides extra functionality for supporting
surface shaders (in other words, nodes that can be connected to the surface slot on
the shading engine, generally classified with shader/surface).
For more details, see the API documentation for the new classes: MPxShadingNodeOverride, MFragmentManager and MPxSurfaceShadingNodeOverride, as well as the updates to the Maya Viewport 2.0 API Guide.
Shader Instance Enhancements
- There have been a number of modifications to the texture API that enhances how color
textures are acquired, cached and updated:
- For acquisition, the acquireTexture() methods on MTextureManager have been modified to allow NULL data to be passed over on creation and to allow
for unnamed textures (empty string). Unnamed textures are not cached by the internal
texture caching system; as a result, the acquisition creates a new texture for each
method call. The behavior of named textures remains the same. If a texture with that
name exists in the cache, then it is returned.
- In general, continuously reacquiring a texture is not recommended. Therefore, new
interfaces that perform updates of existing textures have been added to MTexture:
- MStatus update(const void* pixelData, bool generateMipMaps, unsigned int rowPitch=0);
- MStatus update(const MImage &image, bool generateMipMaps);
- Along with the new method MTexture::bytesPerPixel(), and the existing method MTexture::rawData() there are a number of different ways that textures can be updated:
The existing plug-in hwAPITextureTest and a new plug-in viewImageBlitOverride demonstrate various methods of performing a color texture update. The first has a
new option to invert the pixels in a texture before displaying, and the latter allows
the updating of a texture for each refresh of a render override (MRenderOverride).
- MRenderUtil::eval2dTexture() allows the evaluation of supported texture nodes at one or more (u,v) positions.
- New interfaces have been added as convenience methods to acquire textures which are
suitable for rendering to the depth buffer:
- Unlimited light access:
- Shadow updates “by request”
- Enhanced lighting / shadowing interfaces for render overrides
- Generally, lighting information is only updated during a scene render (MSceneRender). If a shadow request is performed from within a user operation (MUserRenderOperation) in a custom render override, then only the last available lighting information is
available. If a user operation requires lighting information, the new virtual method
MUserRenderOperation::requiresLightData() can be overridden and set to return true.
- To allow for a scene render in a render override to access information such as shadow
maps after update, two new methods have been added: MSceneRender::preSceneRender() and MSceneRender::postSceneRender(). They are called before and after either: shadow map update, or the rendering of
the scene. At this time, the current draw context is available, and hence lighting/shadowing
- An example which uses the new interfaces is the new viewRenderOverrideShadows render override plug-in. This plug-in performs a user operation to queue shadow requests
and then uses them in a custom scene render. The pre-scene render method is overridden
to extract the requested shadow maps for use during scene rendering by a custom shader.
Light and shadow information beyond the light limit can be accessed.
Render Item Enhancements
- Instances of MRenderItem may no longer be created or deleted directly. Plug-ins must now use the static Create() and Destroy() methods on MRenderItem. This change addresses stability issues encountered when the allocation/deallocation
of the memory occurs in different DLLs.
- Can now specify the “Bounding Box” viewport mode for render items.
- Can now set the transform matrix for render items.
- Can now set whether or not a render item should be included in post-effects such as
screen-space ambient occlusion or motion blur.
- The “depth priority” of a render item can now be set. “Depth priority” sets how far
towards the active camera a render item is moved when drawing. This helps to avoid
depth-fighting which can occur for render items with drawing that overlaps each other
in depth. For example, a render item drawing wireframe and another drawing filled
could be drawn at the same depth. To avoid the wireframe item from being obscured
by the shaded item, the depth priority on the wireframe item can be “raised” to avoid
being obscured. See depthPriority() methods for more information.
- Previously, any MRenderItems created by a plug-in had their status for casting and receiving shadows automatically
set each time MPxGeometryOverride::updateRenderItems() was called. This continues to occur for internally created render items, but this
is no longer the case for render items created by the plug-in. It is the responsibility
of the plug-in to either track the status on any associated DAG object, or set the
values based on other logic. Any items that are marked as drawing in wireframe mode
never cast nor receive shadows. Note that render items that draw using lines or points
can still cast shadows as long as they are not marked to draw in wireframe mode. The
plug-in apiMeshShape provides an example that demonstrates various usage scenarios.
- Although the following methods are exposed on MRenderItem, they have no effect on internally created render items:
- The setExclucedFromPostEffects() method only disables screen-space ambient occlusion if the render item is marked
as drawing in shaded or textured mode. If the item is marked as drawing in wireframe
mode, then all post-effects are disabled (screen-space ambient occlusion, motion blur
- The methods on MStateManager for acquiring state objects are now static; therefore, states can now be both created
and deleted without access to an MDrawContext. Only activating states require a draw context.
Pass Information Enhancements
- There are a few new pass context semantics which have been exposed as part of the
addition of the MUIDrawManager interface:
- UI geometry : UI is being drawn
- Pre-UI geometry : UI drawn before the scene (for example, the ground plane).
- Post UI geometry: UI drawn relative to filled drawing (for example, wireframe or components
on a surface).
- Opaque UI : Opaque UI is being drawn.
- Transparent UI : Transparent UI is being drawn.
- Xray UI : UI in x-ray mode is being drawn.
Render Override Enhancements
- Fixed so that post-effects do not affect scene render operations which only draw the
- Ability to explicitly disable post-effects for scene render operations.
- MQuadRender now allows for the specification of state setters. By default, when rendering the
geometry for a quad render operation, blending is disabled, depth write is disabled,
and culling is disabled. Any of the following methods can be implemented by classes
derived from MQuadRender to replace the default behavior for a given state:
- virtual const MDepthStencilState* depthStencilStateOverride(); // Override depth-stencil
- virtual const MRasterizerState* rastersizerStateOverride(); // Override rasterizer
- virtual const MBlendState* blendStateOverride(); // Override blend state
If an override is specified for a given state, then the default state is used for
those other states that are not overridden.
The viewImageBlitOverride plug-in from the devkit provides an example of overriding the depth write state.
- MRenderer::theRenderer() now takes an optional initializeRenderer parameter. Passing false suppresses full initialization of the renderer. This can
speed up the loading of plug-ins by allowing them to register their rendering overrides
without the overhead of full renderer initialization.
Change Management Enhancements
- There is a new method on MRenderer that informs Maya that lights and shadow maps in the scene need to be re-evaluated:
MRenderer::setLightsAndShadowsDirty(). This is useful, for example, for shaders that can modify the geometry of an object
through hardware tessellation. Maya cannot automatically detect that the geometry
has changed in such a case; therefore, it is up to the shader to notify Maya when
changes occur that would require shadows to be recomputed.
- MRenderer::disableChangeManagementUntilNextRefresh() can be used to avoid the overhead of Viewport 2.0 processing changes to the scene
when large changes are being made that do not require viewport updates.
Draw Override Enhancements
- The prepareForDraw() interface now accepts MFrameContext as a parameter as follows:
virtual MUserData* prepareForDraw( const MDagPath& objPath, const MDagPath& cameraPath,
const MFrameContext& frameContext, MUserData* oldData) = 0
- Because occasionally geometry information is computed based on viewport attributes
(for example, viewport size); therefore, plug-in developers may require this information
in preparing for the draw data stage.
Geometry Override Enhancements
- Switching between templating and not templating a Maya DAG object automatically toggles
the visibility of shaded render items, which makes this consistent with the logic
used for the default viewport interface. Plug-ins can override this behavior as desired
to disable/enable any or all of these items.
- Improvements to the apiMeshShape example that uses MPxGeometryOverride. The code demonstrates the following:
- Drawing the wireframe in different display modes (display mode detection), and not
just when the object is active (active display mode) .
- Drawing of dormant and active vertices using the “fat point” stock shader.
- Sample code for acquiring thick line and dash line stock shaders.
- Support for hiding render items when the object is templated and appropriate render
items for drawing templates.
- Usage of new MRenderItem::depthPriority() methods to avoid depth-fighting between UI drawing (for example active and dormant
Maya Callback Enhancements
MFrameContext is a new interface for Maya 2014. It is designed to provide information which is
available per frame render. This includes information such as render targets, viewport
size and camera information.
In terms of relative scope, MFrameContext can be thought of as encompassing the time period for a one or more "passes" (MPassContext) and the time period for actual drawing (MDrawContext).
MDrawContext is derived from MFrameContext and provides its own implementation for all virtual methods. The values returned
from these methods may differ slightly between MFrameContext and MDrawContext as MFrameContext retrieves the values from Maya and MDrawContext retrieves the values from the GPU device state. Also, MFrameContext::getMatrix() is not able to return values for any matrix type requiring the object-to-world matrix,
as that information is only available at draw time.
Frame context information available includes:
- Camera and view information.
- Viewport and active render target information.
- Display style (mimicking the Viewport 2.0 render globals and viewport options)
- Lighting mode and light limit (same)
- Indication of which post effects are active
- Indication of which transparency algorithm is used
- Global line width setting in the viewport menu
MPxSubSceneOverride is a new interface for Maya 2014. It is an alternative to MPxDrawOverride and MPxGeometryOverride, and is specifically optimized for representing plug-in DAG objects in Viewport 2.0
that need to produce a large number of independent drawable objects. For example,
a plug-in node that can define a whole sub-scene (such as the gpuCache plug-in) is a good fit for this interface as a single node may need to produce tens
of thousands of drawable objects.
MPxSubSceneOverride falls in between MPxDrawOverride and MPxGeometryOverride with respect to the amount of control given to the implementation. MPxDrawOverride allows full control over the entire draw of the object, but as a result the implementation
is entirely responsible for the draw. MPxGeometryOverride is relatively simple to work with, but as a result only limited control of the draw
is available. MPxSubSceneOverride can fully define all render items, geometry and shaders, providing a high degree
of control. However, this definition is abstracted from the hardware draw API; therefore,
only one implementation is needed to get support for both DirectX and OpenGL. Furthermore,
Maya handles drawing of the render items and thus the items can participate more fully
in the Maya rendering pipeline (including screen-space effects such as screen-space
ambient occlusion, transparency sorting, shadow casting/receiving, and so forth).
The Maya 2014 API explicitly does not call back to render overrides to render ghosted
Previously, when the dag object for which an override is attached to is set to be
ghosted, it is possible for the render item or draw code to be called multiple times
– once for each ghost.
This no longer occurs. Thus, it is up to the plug-in writer to write code to perform
the plug-in's own ghosting.
MPxDrawOverride, MPxGeometryOverride and MPxSubSceneOverride are the affected classes.
The port of the MetaData C++ API to the .NET API has been revamped and improved significantly
- support standard .NET interfaces such as IDictionary and IEnumerable on key classes
- simplify the concept of data description and data access where the user can now simply
provide a .NET type for the data. This completely replaces the need for using the
classes Structure and Handle as they are now created automatically from this client type.
For more information, see MetaData.
New API for Reference Edits
- MPxEditData gives you the ability to create your own custom data to associate with reference
New API for Generic Metadata (blind data)
- MFileIO - Added the setMetadata(), deleteMetadata() and metadata() methods to allow the specification of persistent scene-level metadata (that is, it
is stored with the scene file).
New External Content API
- MExternalContentInfoTable is used to store the locations of all the external content (files, textures, and
so forth) that is needed by a node to perform its work. MExternalContentLocationTable is used to pass updates to those locations to the node (for example, from the ).
- getExternalContent(), setExternalContent() and addExternalContentForFileAttr() have been added to MFnDependencyNode and MPxNode to access and modify the external content of nodes.
- MnObject::fnObject and fOwn have been made private. These should not been used and if they are, modifications
must be made accordingly.
- MRampAttribute has had a number of methods added to make it easier to use. setRamp() makes it easier to set new values on the ramp and createRamp() makes it easier to create a ramp with initial values. Also added are sort(), pack(), and hasIndex().
- The evalNoSelectNotify command executes a command with selection change notifications disabled. This can
significantly improve performance in those situations where a script is executing
a large number of commands which change the current selection (for example, createNode), but where only the final selection state is significant.
- Plug-in writers should be aware that, in order for a plug-in transform to be recognized
in Viewport 2.0, the appropriate classification string drawdb/geometry/transform must be added when registering the transform. This must be done so that:
- Local rotation axis and pivots draw.
- Transforming the object moves any children parented under it in the DAG.
For example, for the rockingTransform plug-in, the code is as follows:
// Classify the node as a transform. This causes Viewport
// 2.0 to treat the node the same way it treats a regular
// transform node.
const MString classification = "drawdb/geometry/transform";
status = plugin.registerTransform("rockingTransform",
This functionality was available beginning Maya 2012.
In Maya 2014, registerTransform() has been updated to automatically add the drawdb/geometry/transform classification if no other drawdb classification is specified. The getClassification command documentation has also been updated with the general list of classifications
recognized by Viewport 2.0.
Updates to Viewport 2.0 API chapter