Write fragments and fragment graphs to render to the viewport

Introduction

A fragment is a procedure or function definition in a high level language. It has typed inputs and outputs, and executes some procedure on the inputs to produce the output(s).

You can write shading fragments, or you can write script fragments that execute a series of commands to set up parameters and states and clear or render to various targets.

Fragments may then be connected into fragment graphs. A fragment graph does not contain commands; instead, it instantiates a set of fragments and describes the connections between them.

A single script fragment or fragment graph can be stored in a .xml file.

A set of script fragment and fragment graph xml files are provided with the Maya installation at the bin/ScriptFragment directory of your installation directory. These fragment and fragment graphs are used to render to Viewport 2.0.

Default.xml is the main fragment graph that describes how Maya renders in Viewport 2.0. When this fragment graph is executed, the scene is displayed in the viewport.

It connects various fragments and fragment graphs such as Maya_3d_Renderer, which connects fragment graphs such as HoldOutPasses and Maya_PostEffects, which connects fragments and fragment graphs such as the mayaUIDrawPass and Maya_SSAO, and so forth.

These xml files serve as examples of how to write your own script fragment and fragment graphs for a fragment renderer.

When creating your own fragment renderer, you can re-use existing Maya fragments, and only write the xml for the fragments that you want to customize. For example, to create your own custom motion blur pass, you can write a motion blur fragment and combine it with existing Maya fragments.

One way to accomplish this would be to do as follows:

  1. Copy the existing Maya fragment/fragment graph .xml files into a new folder.
  2. Modify the fragment/fragment graph that you want to customize and rename it.
    NOTE:Directly modifying the files in bin/ScriptFragment is not recommended, as you may inadvertently corrupt Maya. It is therefore recommended that the fragment files first be copied into a new folder.
  3. Modify the main fragment graph (default.xml) to point to your modified fragment/fragment graph (from step 2), and give the main fragment graph a new name.

Some procedurals cannot be easily represented as script fragments, and are provided as hardcoded C++ procedural fragments with Maya. You can combine C++ procedural fragments with script fragments in your fragment graph.

TIP:

To reproduce Maya's renderer, first initialize an MRenderOverride with a list of operations such as the following:

class FragmentRenderOverride(omr.MRenderOverride):

    def __init__(self, name):
        self.operatioIndex = 0
        self.operations =  [omr.MSceneRender("myRendererSameAsMaya", “default”),
                           omr.MHUDRender(),
                           omr.MPresentTarget("present")]

Where “default” is the name of the render fragment that Maya uses when not overridden. default.xml can be found in the bin/ScriptFragment folder of your Maya installation directory.

Default only draws the beauty pass and does not include the drawing of UI, shadow maps, HUD, and so forth that are part of MSceneRender.

API classes and interfaces

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.

Fragment and fragment graph XML definition

Parts of the fragment description

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" >
  • Set the name attribute to the internal name of the fragment.
  • You can set the uiName to be the same as its internal name, or provide it with an external name.
  • Set the type attribute to sceneEffect.
  • The class attribute must be set to ScriptFrament for fragments (and FragmentGraph for fragment graphs.)
  • Set the version attribute to identify changes between releases. In most cases, you can set this value to 1.0, as in this example.
  • Set the feature_level attribute to the highest feature level support required by the effects and features used in the passes. For example, feature_level 30 is equivalent to DirectX 10. In most cases, setting this value to 30 as in this example is sufficient.

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.

Parts of a fragment graph definition

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>