Multiple Render Targets



Introduction

With the advent of Synthclipse 1.1.0 it is possible to render to more than one buffer at once. This feature in the OpenGL programming world is known as “Multiple Render Targets”. It can be used to save time. For example, if one wants to use Synthclipse as generator of data that will be further post-processed in some professional graphics software, and for that purpose one needs to have depth and color buffers separately, then one no longer needs to render everything twice (one for color and one for depth buffers). With Multiple Render Targets one can just define two outputs in a fragment shader:

uniform vec3 iResolution; // viewport resolution (in pixels)

layout(location = 0) out vec4 FragColor; //! <output components="4" saveName="color" type="half_float" />
layout(location = 1) out float DepthColor; //! <output components="1" saveName="depth" type="float" />
layout(location = 2) out vec2 OtherColor; //! <output components="2" saveName="other" type="float" />

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;

    FragColor = vec4(uv, 0.0, 1.0);
    DepthColor = uv.x;
    OtherColor = uv;
}

How many outputs/Render Targets can be used depends on graphics card, but usually it is at least 8. Synthclipse prints the exact number in the Console View (when more than one output is used in a shader):

Max count of MRTs

Every output can be previewed in the Viewport View using “Render Target” menu:

Render Target Menu

When recording, by default, there will be generated as many images per frame, as there is Render Targets. Render Target with “layout(location = 0)” will have no special suffix, but targets with locations higher than 0 will have appended “saveName” attribute to their name, e.g.

  • output.png for “layout(location = 0) out vec4 FragColor; //! <output components=”4“ saveName=”color“ type=”half_float“ />”
  • output.depth.png for “layout(location = 1) out float DepthColor; //! <output components=”1“ saveName=”depth“ type=”float“ />”

One can also limit image generation to some subset of defined Render Targets by clicking on the “Outputs (N/M)” button in the Recording View:

Outputs button

Outputs dialog

Syntax

Output command has the following syntax:

layout(location=LOCATION) out GLSL_TYPE GLSL_VARIABLE_NAME; //! <output components="BUFFER_COMPONENTS" type="BUFFER_CHANNEL_TYPE" saveName="SAVE_IMAGE_NAME" />

Examples:
layout(location = 0) out vec4 FragColor; //! <output components="4" saveName="color" type="half_float" />
layout(location = 1) out float DepthColor; //! <output components="1" saveName="depth" type="float" /> 

Where:

  • LOCATION is an integer. It must start from 0 and every successive output needs to have value greater by 1 than previous.
  • GLSL_TYPE is ordinary GLSL data type, like float, int, vec2, vec3, vec4, ivec2, uvec3, etc.
  • GLSL_VARIABLE_NAME is user defined variable name that will be referenced in the shader.
  • BUFFER_COMPONENTS is an integer from 1 to 4 (inclusive). It means how many components are per pixel in underlying buffer.
  • BUFFER_CHANNEL_TYPE can have the following values: byte, half_float, float, uint. It means how many bits are saved per component (byte - 8, half_float - 16, float - 32, uint - 32) and what binary representation the component will have
  • SAVE_IMAGE_NAME is used during recording. It is a string that is attached to the base output file name to distinguish between Render Targets. In case of single OpenEXR file with multiple parts (“Save all to single EXR file” option) it is used as a part name.

Supported image formats

Image formats

Supported output image formats are:

  • png
  • jpg
  • bmp
  • exr (OpenEXR)

In case of png, jpg, bmp there are always saved 3 components (RGB) with 8 bits per channel, no matter how many components and what type of output you have declared (missing components have implicit zero value). To fully exploit Multiple Render Targets feature it is advised to use OpenEXR image format. OpenEXR supports various channel formats:

  • float32 - type=“float”, GLSL corresponding type : float
  • float16 - type="half_float’, GLSL corresponding type: float (with less precision than previous)
  • unsigned int32 - type=“uint”, GLSL corresponding type: uint

EXR is not limited to 3 channels. One can also use: 1, 2 or 4 channels.

By default, for every image type, each Render Target is saved to a separate file, but in case of OpenEXR you have an option save all Render Targets to one multi-part exr file.

Examples

MRT examples are build in Synthclipse and are available via *Synthclipse main menu -> Examples Multiple Render Targets Examples…"

MRT examples menu

MRT examples dialog