MPxSubSceneOverride is the API entry point for defining high-level Viewport 2.0 drawing of plug-in DAG objects that require a large number of drawable entities. Although it can be used with any type of DAG object, MPxSubSceneOverride is designed to be an efficient and tightly integrated path for supporting “scene-cache” style nodes that manage a large and complex set of objects in a way that is opaque to the rest of Maya. The gpuCache plug-in that is used in Maya’s scene assembly workflow is a good example of this sort of DAG object type.
Implementations of MPxSubSceneOverride must be registered with MDrawRegistry using classification strings. The classification string must begin with "drawdb/subscene" in order to be properly recognized by the system. DAG objects with classification strings that satisfy the override classification string are evaluated using the override.
MPxSubSceneOverride is draw-API agnostic. Implementations operate using the MRenderItem interface and are simply required to manage a collection of MRenderItem objects to draw all instances of the associated DAG object. One implementation of the override is created for each object in the Maya scene with a classification string that satisfies the classification string used when registering the override. If the associated DAG object is instanced, the override is responsible for drawing all instances.
The collection of render items is stored in an MSubSceneContainer object. This container is suitable for storing and accessing large numbers of render items (tens of thousands or more) in a high performance manner. Implementations are responsible for assigning a shader and an optional matrix to each render item, and must also provide the geometry for each render item as required by its shader. Geometry may be shared between render items and management of the geometry is up to the implementation.
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 is allowed to 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 required to get support for both DirectX and OpenGL. Furthermore, Maya handles the drawing of the render items, and thus the items can participate fully in the Maya rendering pipeline (including screen-space effects such as screen space ambient occlusion, transparency sorting, shadow casting/receiving, and so forth). Finally, render items may specify which draw modes they should draw in (wireframe, shaded, textured, bounding box); therefore, there is no need for the implementation to track these modes manually.
MPxSubSceneOverride has two stages, and the stages are invoked on every frame before drawing begins. In each stage, an instance of MFrameContext is provided to give some information about the current state of the renderer. The implementation is also free at any time to query any information it needs directly from Maya.
In the requiresUpdate() stage, implementations of MPxSubSceneOverride are required to notify Maya if the set of render items for the associated DAG object needs to be updated. If not, then the second stage is skipped. This is an opportunity to avoid heavy processing if the associated node has not changed since the last update.
In the update() stage, the implementation may add or remove render items from the container and it may modify existing render items. For each render item in the container, the implementation is required to call MPxSubSceneOverride::setGeometryForRenderItem() to provide the geometry for the render item. Render items without geometry do not draw. The render items may only be modified during the update stage. It is an error to do so at other times and doing so may result in instability.
After the update stage completes, the render items in the container are drawn as long as they are: enabled, have a valid shader, have geometry that fulfills the requirements of the shader, and are not filtered out due to viewport draw modes (that is, wireframe vs. shaded). The render items persist in the container until they are explicitly removed. Therefore, if the data that needs to be drawn is static, then the implementation of MPxSubSceneOverride could return false on all calls to requiresUpdate() following the initial update stage.
See the MRenderItem interface for more information on how a render item may be modified to control its display in Viewport 2.0.