Maya's viewport relies on a system of fragments (scripts serialized in an XML format) of two different types:
A set of script fragment and fragment graph XML files is provided with the Maya installation in the bin/ScriptFragment
subdirectory of your installation directory.
In Maya 2020 and earlier releases, default.xml
was the top-level fragment graph that defined the default implementation of the beauty pass (including scene and post-effect passes but excluding shadow map and various UI and HUD passes).
It connected various fragments and fragment graphs such as Maya_3d_Renderer.xml
, which connected fragment graphs such as HoldOutPasses.xml
and Maya_PostEffects.xml
, which in turn connected fragments and fragment graphs such as mayaUIDrawPass.xml
and Maya_SSAO.xml
, and so forth.
Some of the fragments referenced in these graphs are implemented as hardcoded C++ procedural fragments.
In newer versions of Maya, default.xml
and its dependencies are still shipped with Maya but the default beauty pass implementation has been redesigned and can no longer be described by a single script fragment graph.
In an MRenderOverride
plug-in, the beauty pass is represented with the MSceneRender
operation. When constructing the MSceneRender
, the fragmentName
parameter can be used to provide the name of a custom script fragment or fragment graph to override the default Maya beauty pass implementation, for example:
class FragmentRenderOverride(omr.MRenderOverride):
def __init__(self, name):
self.operatioIndex = 0
self.operations = [omr.MSceneRender("myRendererSameAsMaya", fragmentName=“customBeauty”),
omr.MHUDRender(),
omr.MPresentTarget("present")]
You can use the XML files shipped in the bin/ScriptFragment
directory as a reference when writing your custom fragment however modifying files in that directory directly is not recommended, to avoid corrupting Maya.
API entry points for creating a fragment renderer are as follows. See the viewRenderOverrideFromFragments plug-in in the Developer Kit and Create a fragment renderer plug-in example for example usage of these interfaces.
MRenderer::getFragmentManager()
to access the Fragment Manager, and call MFragmentManager::addFragmentGraphFromFile()
to register a script fragment or fragment graph.Create your scene render using this MSceneRender
constructor that allows you to provide the name of the fragment with which you want to render the scene.
MSceneRender (const MString &name, const MString &fragmentName)
Initialize an MRenderOverride
with a list of MRenderOperation
s, one of which is the custom render operation, derived from MSceneRender
.
MRenderer::registerOverride()
.MSceneRender::getParameters()
to return a pointer to MRenderParameters
, which is a block of render input parameters used to control the rendererMRenderParameters::setParameter()
to pass the values to the render fragment used by the custom MSceneRender
.(Optional) Derive from the MRenderScriptCallback
class to create a callback function that can be registered and called from your script fragment .xml
. Implement the execute()
function which allows you to obtain the MRenderParameters
from the current renderer graph and three optional values coming from the script. Use this method to compute any desired behavior and call MRenderParameters::setParameter()
to pass the results back to the script or to other connected fragments in the graph. See the Call command in the Script fragment commands topic for more information.
The MRenderer::registerScriptCallback()
and MRenderer::deregisterScriptCallback()
interfaces allow you to register/deregister an MRenderScriptCallback
. After registering, this callback can be called using the Call
command in your script fragment .xml.
Refer to maya_DepthPrePass.xml
for an example.
All fragments are contained within the compound element fragment.
<fragment uiName="maya_DepthPrePass" name="maya_DepthPrePass" type="sceneEffect" class="ScriptFragment" version="1.0" feature_level="30" >
The fragment definition also contains the following elements:
An optional description element, where a description is wrapped in a CDATA block
<description>
<![CDATA[
depth pre-pass: make depthStencil & linear, readable opaque depth texture]]>
</description>
A required set of input parameters called properties.
Use the format <type name ="myParam">
, where type is the type of the parameter (for example, int, float4, and so forth), and name is the required name of the parameter (unique within the set).
This may include pre-defined, known inputs in Maya; for example, preOpaqueUIList, transparentBitmapsList, camera, viewport, and so forth.
<properties>
<countedObject name="preOpaqueUIList" />
....
</properties>
A set of initial values for parameters without input connections
To define parameters with an initial value, in the value element, use the format:
<type name ="myParam" value ="…" />
The exact format of the value string is determined by the type of the parameter. Multiple values are given using comma-separated lists; for example, “0,1,3” would match an int3 or float3 parameter.
All attributes in the fragment graph that share the same name are initialized with these values.
<values>
<float4 name="viewport" value="0.000000,0.000000,1.000000,1.000000" />
....
</values>
A set of output parameters called outputs:
<outputs>
<target name="depthOut" />
<target name="opaquedepthtexture" />
</outputs>
An implementation element containing a list of commands. Set render to OGS and language to ScriptInterpreter.
Each command is defined by a single element of the form:
<command value="theValue" />
<implementation render="OGS" language="ScriptInterpreter" version="0.1" >
<scriptCommands>
<AcquireTarget name="localZ" format="EFORMAT_R32_FLOAT" size="@finalDesc.size" relSize="1.0,1.0" msaa="0" />
....
</scriptCommands>
</implmentation>
See Script fragment commands for a list of available commands.
When listing commands, use the symbol @ to indicate that the value should be obtained from a parameter instead of being set by a local value. For example, in the code snippet above, the value is obtained from the finalDesc parameter.
As described earlier, various script fragments and fragment graphs can be connected to one another to form a single fragment graph.
Refer to Maya_PostEffects.xml
for an example.
All fragments are contained within the compound element fragment_graph as follows:
<fragment_graph name="Maya_PostEffects" ref="Maya_PostEffects" class="FragmentGraph" version="1.0" feature_level="0" >
Set the ref attribute to the internal name of the fragment graph.
You can set the name attribute to be the same as the internal name, or provide it with an external name.
The class attribute must be set to FragmentGraph.
The fragment_graph definition also contains the following elements:
Fragments
List all the fragments contained in this graph; the order of the listing is not important.
<fragments>
<fragment_ref name="Maya_UI" ref="mayaUIDrawPass" />
....
</fragments>
Set the ref attribute to the internal/default name of the fragment; that is, the name defined by the name attribute in the fragment element in the XML file.
You can set the name attribute to be the same as the ref attribute. Alternatively, you can set it to a different name for use in different instances. This way, if the same attribute is used in two different passes, the attribute can have different connections in the two passes.
For example, refer to Maya_PostEffects.xml
, where the Maya_PostEffects
fragment graph includes the graph Maya_SSAO
:
<fragment_ref name="Maya_SSAO" ref="Maya_SSAO" />
It then connects the Maya_SSAO.res
to Maya_MotionBlur.input
:
<connect from="Maya_SSAO.res" to="Maya_MotionBlur.input" name="input" />
To create different connections to or from Maya_SSAO
in another pass or fragment graph, you can instead do the following:
<fragment_ref name="Maya_SSAO_instance1" ref="Maya_SSAO" />
Then connect it as follows:
<connect from="Maya_SSAO_instance1.res" to="Maya_MotionBlur.input" name="input" />
Maya_MotionBlur.input
can now receive a different input in other fragment graphs.
Connections
Specify all the connections between fragments. Each connect element specifies one output, from, connected to one property input, to.
Inputs may have only one connection, but outputs may have an arbitrary number. Unconnected inputs are either system supplied variables, matched by semantic, or become tweakable through the API.
<connections>
<connect from="mayaPreUIScript.output" to="Maya_UI.final" name="final" />
....
</connections>
Note:
final
denotes the buffer that results should be drawn into at the end of the operation.
Properties
List all unconnected input parameters by providing the name and attribute of its sub-fragment/fragment graph, and the external name that you want to use to represent it.
For example:
<properties>
<float4 name="viewport" ref="Maya_SSAO.viewport" />
....
</properties>
Maya_SSAO is a sub-fragment graph and its viewport attribute should be exposed using the alias viewport.
Values
Define initial values for unconnected input parameters.
<values>
<float4 name="viewport" value="0.000000,0.000000,1.000000,1.000000" />
....
</values>
Outputs
Specify the outputs here, and list the primary output first.
<outputs>
<target name="output" ref="Maya_UI.output" />
</outputs>