Scene rendering and any post-processing on a Viewport is defined by its RenderPath object, which can either be read from an XML file or be created programmatically.
The render path consists of rendertarget definitions and commands. The commands are executed in order to yield the rendering result. Each command outputs either to the destination rendertarget & viewport (default if output definition is omitted), or one of the named rendertargets. MRT output is also possible.
A rendertarget's size can be either absolute, divide the destination viewport size, or divide the destination rendertarget size. If size definition is omitted, it will match the destination rendertarget size. For an example of rendertarget definitions, see the inbuilt bloom effect in Bin/Data/PostProcess/Bloom.xml.
The available commands are:
- clear: Clear any of color, depth and stencil. Color clear can optionally use the fog color from the Zone visible at the far clip distance.
- scenepass: Render scene objects whose material technique contains the specified pass. Will either be front-to-back ordered with state sorting, or back-to-front ordered with no state sorting. For deferred rendering, object lightmasks can be optionally marked to the stencil buffer. Vertex lights can optionally be handled during a pass, if it has the necessary shader combinations. Textures global to the pass can be bound to free texture units; these can either be the viewport, a named rendertarget, or a 2D texture resource identified with its pathname.
- quad: Render a viewport-sized quad using the specified shaders. Textures can be bound and additionally Vector4 shader parameters can be specified.
- forwardlights: Render per-pixel forward lighting for opaque objects. Shadow maps are also rendered as necessary.
- lightvolumes: Render deferred light volumes using the specified shaders. G-buffer textures can be bound as necessary.
A render path can be loaded from a main XML file by calling LoadParameters(), after which other XML files (for example one for each post-processing effect) can be appended to it by calling Append(). Rendertargets and commands can be activated or deactivated by calling SetActive() to switch eg. a post-processing effect on or off. To aid in this, both can be identified by tag names, for example the bloom effect uses the tag "Bloom" for all of its rendertargets and commands.
It is legal to both write to the destination viewport and sample from it during the same command: pingpong copies of its contents will be made automatically. If the viewport has hardware multisampling on, the multisampled backbuffer will be resolved to a texture before the first command which samples it.
The render path XML definition looks like this:
<renderpath>
<rendertarget name="RTName" tag="TagName" active="true|false" size="x y"|sizedivisor="x y"|rtsizedivisor="x y"
format="rgb|rgba|r32f|rgba16|rgba16f|rgba32f|rg16|rg16f|rg32f|lineardepth" filter="true|false" />
<command type="clear" tag="TagName" active="true|false" clearcolor="r g b a|fog" cleardepth="x" clearstencil="y" output="viewport|RTName" />
<command type="scenepass" pass="PassName" sort="fronttoback|backtofront" marktostencil="true|false" usescissor="true|false" vertexlights="true|false">
<output index="0" name="RTName1" />
<output index="1" name="RTName2" />
<output index="2" name="RTName3" />
<texture unit="unit" name="viewport|RTName|TextureName" />
</command>
<command type="quad" vs="VertexShaderName" ps="PixelShaderName" output="viewport|RTName" />
<texture unit="unit" name="viewport|RTName|TextureName" />
<shaderparameter name="ParameterName" value="x y z w" />
</command>
<command type="forwardlights" uselitbase="true|false" output="viewport|RTName" />
<command type="lightvolumes" vs="VertexShaderName" ps="PixelShaderName" output="viewport|RTName" />
<texture unit="unit" name="viewport|RTName|TextureName" />
</command>
</renderpath>
Note the special "lineardepth" format available for rendertargets. This is intended for storing scene depth in deferred rendering. It will be D3DFMT_R32F on Direct3D9, but RGBA on OpenGL, due to the limitation of all color buffers having to be the same format. The file Samplers.frag in Bin/CoreData/Shaders/GLSL provides functions to encode and decode linear depth to RGB.
Hardcoded scene passes
Otherwise fully customized scene render passes can be specified, but there are a few exceptions related to forward per-pixel lighting.
- The "light" and "litbase" passes will be automatically rendered by the forwardlights command, interleaved with shadow map rendering as necessary.
- The "litalpha" pass for transparent objects is automatically merged with the "alpha" pass, if it exists in the render path definition. The idea is that all transparent objects are sorted back to front, and their base passes (the actual "alpha" pass) are rendered first, followed by their additive pixel-lit passes. The "usescissor" flag in the scenepass command should be set to true, so that scissor rectangles limit the effect of lights on transparent objects.
- The forwardlights command can optionally disable the "litbase" pass optimization without having to touch the material techniques, if a separate opaque ambient-only base pass is needed. By default the optimization is enabled.