Programming
Fundamentials
Setting Up Development Environment
UnigineScript
High-Level Systems
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Core Library
Containers
Engine Classes
Node-Related Classes
Rendering-Related Classes
Physics-Related Classes
Bounds-Related Classes
GUI-Related Classes
Controls-Related Classes
Pathfinding-Related Classes
Utility Classes

Rendering Sequence

Unigine 2 was switched to the full-deferred renderer. All opaque (non-transparent) geometry is rendered in the deferred pass. The forward rendering pass can be enabled for special transparent objects, however transparent objects also can be rendered in the deferred pass.

This article introduces the detailed Unigine 2 rendering pipeline including all the auxiliary stages which can be skipped by user.

Rendering Pipeline

Here is a rendering pipeline, all stages are performed during one frame composition. Some stages can be switched off if it is necessary: decals rendering stage, auxiliary pass, post-materials, etc.

The schematic representation of the rendering pipeline helps you to understand the major stages of the rendering order.

The schematic representation of the rendering pipeline

During the frame rendering, we will observe the simple test scene with variety of materials (transparent and opaque), reflection probes, decals, planar reflections, different light sources.

The demonstration scene in UnigineEditor
  1. Common pass
  2. Calculating Intersections
  3. Rendering shadow maps
  4. Rendering dynamic reflections
  5. Deferred pass for opaque objects
  6. Deferred pass for transparent objects
  7. Forward pass for transparent objects
  8. TAA
  9. Render Post Materials
  10. Rendering Shadow Shafts
  11. Rendering Camera Effects
  12. Final Screen Composition
  13. Post Materials
  14. Rendering Visualizer
  15. Rendering GUI

Common Pass

Common pass is the first pass of the rendering: in this pass LUTs, Environment cubemap are rendered. They are rendered only once before all the geometry on the scene.

Textures are rendered during this pass will be used further for scattering rendering and non-dynamic reflections..

Environment cubemap is composed from 6 pieces (each 256x256 px).

Schematic representation of the 1x256 LUT textures.

LUT textures are represented as 1x256 px textures taken from the current state of the loaded LUT textures for scattering.

Calculating Intersections

This is the preparing stage before geometry rendering. The engine analyzes the visible part of the scene to know which objects it should draw. The engine do the following:

  • Checks the intersections with frustum.
  • Finds all the light sources on the scene.
  • Finds all the surfaces that should be rendered (taking into account occluder objects).
  • Sorts Environment Probes by size (from large to small).
  • Sorts Decal objects by their rendering order.

Rendering Shadow Maps

After intersection calculations, shadow maps are rendered. The way of rendering these maps depends on a light source type.

World Light

The engine creates cascaded shadow maps for the world light sources.

Rectangular shadow cascades.

World Light's shadow map is rendered into orthographic projection.

Notice
You can specify the number of cascades in the Shadow tab of the World Light source in the Nodes window.

Shadow map of the world light source is rendered into texture divided into four parts (since the 4 is the maximum quantity of shadow cascades).

Shadow map of the world light source.

Hence the shadows near the camera have higher resolutions, while shadows that far away from camera have fewer details.

Omni Light

For Omni light sources perspective projection is used. For generating shadow maps 6 cameras are used.

Using a lot of Omni lights can be sufficiently decrease the performance.

Proj Light

Shadow maps for Proj light sources are rendered only once, because only 1 camera is used.

Notice
It is better to use Proj lights instead of Omni for better performance.

Rendering Dynamic Reflections

On this stage the engine renders environment probes' cubemaps and planar reflection textures for dynamic reflections. To render these textures, the engine goes through all rendering pipeline (but misses some passes described below) to create reflections.

Cubemaps are generated by using 6 cameras, planar reflections use only 1 camera. Both render the final image (one more rendering cycle) with some hooks:

  • Textures use shadow maps, that were already generated in the previous shadow maps rendering pass.
  • All post effects are ignored.
  • Final image for dynamic reflections rendered missing TAA.
Notice
Update parameter (that available in the settings window of the Environment Probe object) has influence on the rendering. This parameter specifies how many sides of the cubemap will be rendered during 1 update cycle. The minimal value doesn't always mean the better performance: a model with a lot of polygons (e.g. ~1 million) may cause a lag ("spike"), because other sides will take much less time for rendering.

Deferred Pass for Opaque Objects

This one of the key passes of the rendering: all the opaque geometry is rendered during this pass.

In the end of this pass, the engine has the image with all opaque geometry and scattering.

Native Depth Pre-Pass

The GPU performs a depth-test for surface culling.

This depth buffer stores native depth values z/w, instead linearized values.

The depth data stores in a depth buffer texture format D32F

During this pass the GPU can discard a pixel (the shading for this pixel won't be calculated).

Filling the Buffers

During this step of rendering, the engine fills the G-buffer for shading.

Depth

Depth buffer contains scene objects in the current field of view (found between the near and far clipping planes). Object are rendered as pure geometric models and stored into this buffer.

This depth buffer stores linearized depth values within (0;1) range (where 0 is near clipping plane, 1 is far clipping plane).

The format of the texture is RGBA8 (RT0):

  • RGB channels store compressed depth values. The 24 bit depth value divided into RGB8.
  • A channel stores the transparency for Deferred transparent pass.

Engine depth buffer stores compressed depth (the buffer is linear), whilst the native depth buffer is non-linear.

Diffuse

Diffuse colors buffer stores pure diffuse colors of all material textures:

The format of the texture is RGBA8 (RT1):

  • RGB channels store diffuse color values.
  • A channel stores the microfiber value.
Notice
Set the alpha value to 0, if you don't need the microfiber.
Normal

Normal buffer stores normal vectors for each vertex of geometry which will be necessary to calculate the proper lighting.

The format of the texture is RGBA8 (RT2):

  • RGB channels store compressed normal values (in view space).
  • A channel stores the gloss value.
Specular

Specular buffer stores the specular values of objects on the scene.

The format of the texture is RGBA8 (RT3):

  • RGB channels store specular values.
  • A channel stores the translucent value.

Translucency is used to simulate light shine through objects (leaves, for example).

Velocity

Velocity buffer stores information about the displacement of pixels per frame. When the image is still the buffer is filled with zero (black) values. These values is necessary to make the Temporal anti-aliasing (TAA) and motion blur work.

The format of the texture is RG16F (RT4):

  • RG channels store pixel displacement values (XY coordinates).
Warning
Filling this buffer is mandatory!
Decal Mask

Decal mask buffer contains information about decals.

The format of the texture is R32U (RT5):

  • R channel stores decal mask value.
Notice
Use the render_decals 0 console command to disable rendering decals.
Light Map

Light map buffer is used to add baked light to the scene.

The format of the texture is RGBA16F (RT6):

  • RGB channels store decal mask value.
  • A channel stores surface ambient occlusion (baked).

A channel contains surface ambient occlusion which is baked, ambient occlusion works alongside with it.

Notice
Use the render_surface_ao 0 console command to disable rendering surface AO (the engine will use only RGB channels).
Use the render_surface_light_map 0 console command to disable light map rendering (the engine will use only A channel).

Rendering Decals

During this step of the deferred pass for opaque objects, the engine renders decals. Depending on what textures you add to the decal, the engine adds textures to the current buffers:

Diffuse texture

Normal texture

Specular texture

Notice
If the value of render_decals console variable is set to 0, the engine will skip this rendering stage.

The engine simply adds the decals textures on top of the rendered buffers.

Auxiliary Pass

Auxiliary pass is a type of custom pass. Materials with Auxiliary pass enabled will be rendered in the auxiliary texture.

The engine will skip this pass, if there's no material with enabled Auxiliary pass option.

Rendering Refractions

On this stage of pipeline the refractions are rendered. They are rendered in the Refraction texture to be used in the Deferred Composite.

Rendering Deferred Light Sources

On this step, light sources are rendered into their texture to be applied during the Deferred Composite.

On the demonstration scene we use 3 types of light sources: 1 world light, 1 omni light, 1 proj light.

Notice
For optimization issues, 1 world light source is always rendered during the Deferred Composite step.
If you have 2 or more world light sources, 1 world light source will always be rendered during the deferred composite, other will be rendered during this step.

Proj light source texture

Omni and Proj light sources texture

All lights are added on the single texture to be applied in the deferred composite.

Rendering Deferred Reflections

During this stage of rendering, the engine renders all the reflection probes that are already sorted on the calculating intersection stage.

First (the biggest) Environment Probe reflection applied within its radius.

Second Environment Probe dynamic reflection applied within its radius.

Third (the smallest) Environment Probe reflection applied within its radius.

Reflection Pass

In the reflection pass, planar dynamic reflections (that were already rendered) applied. They use the same texture that was used for Environment Probe reflections.

Planar dynamic reflection applied.

SSAO

Screen-space Ambient Occlusion is rendered in its own texture. It also will be applied on the deferred composite stage.

SSAO texture.

SSR

Screen-space Reflections are rendered in its own texture. It also will be applied on the deferred composite stage.

Scattering

On this stage the scattering is rendered by using Environment cubemap and LUTs textures that were obtained in the Common pass

Scattering texture.

Deferred Composite

During this stage, the engine uses all the necessary textures from the previous stages and passes to create the final image with opaque geometry. The engine combine buffers and calculates shading for the final image of this pass.

Deferred composite is rendered over the Scattering texture

The final image of deferred pass for opaque geometry (excluding the Emission pass).

Notice
During deferred composite stage a world light texture is also rendered.

Emission

Emission pass goes after the deferred composite image created. It applies emission effect over the deferred composite image.

Emission applied.

Deferred Pass for Transparent Objects

This pass is used for materials with specified deferred alpha blend transparency.

During the deferred pass for transparent objects the renderer repeats every step of the deferred pass for opaque objects (excluding SSAO, SSR and decals).

Notice
To enable deferred transparency, use the render_deferred_transparent 1 console command.

Transparent objects are rendered over the opaque objects (deferred buffer) by using alpha blend. Furthermore, places where the alpha equals zero don't participate in shading calculations.

After the deferred pass for transparent objects. Deferred transparent objects appeared.

Notice
Deferred transparency is better to use, when you have a lot of transparent objects or a high-poly transparent models. In other cases, there's no difference in using deferred or forward transparency.

Forward Pass for Transparent Objects

Despite the engine is fully-deferred, forward rendering pass is also available for transparent objects.

During the forward pass (as well as deferred pass for transparent objects) the renderer fills the deferred buffers to let forward transparent object participate in post-effects.

Ambient Pass

During the ambient pass the environment, lightmaps, emission for transparent objects are calculated.

Light Passes

During the light passes for forward transparent objects light is calculated. Render goes only through passes that were specified in the material states.

Ultimately, all the lights for forward transparent objects are added one after another.

After the forward pass for transparent objects.

Filling Deferred Buffers

Forward pass also writes information into deferred buffers to let forward transparent objects participate into post-effects.

Temporal Anti-Anliasing

This pass is used when TAA is enabled. Otherwise, the engine skips this pass and goes to the next one.

After the TAA.

TAA uses previous frames to improve the current frame by using linear interpolation.

Render Post Materials

In this pass, the engine generates procedural textures for Render Post Materials. They are applied after the TAA.

Rendering Shadow Shafts

In this step the engine renders the texture with shadow shafts. That texture will be used on the final screen composition stage.

Rendering Camera Effects

All camera effects are rendered in their own textures: Exposition, DOF, Bloom, etc. They will be used on the final screen composition stage to create the final image.

Final Screen Composition

On this stage, the engine assemble a final image by using all the textures that were rendering in the previous steps.

Final screen.

Post Materials

After the final screen composition, all the post-effects applied.

If the procedural texture is necessary for a post-material, it will be calculated in this step and then the post-effect will be applied to the final composed screen.

Rendering Visualizer

On this stage the engine visualizer is rendered: mesh wireframes, bounding boxes, etc.

Rendering GUI

GUI is rendered last, after all the stages and passes are rendered.

After GUI rendering.

Finally, the engine rendered a single frame!

Rendering Optimizations

In the deferred pass the rasterization process happens only once that reduces the performance costs. After the rasterization process, lights are applied to the necessary buffers to create a final image of the scene.

Notice
Use the render_show_textures console command to show current set of buffers used by the renderer.

In the deferred pass, 42 same non-transparent geometry objects (even if they have different materials) are grouped to be rendered in one draw call. Shadows have their own separate logic: 42 shadows of different meshes with different materials (that based on the mesh_base material) are grouped to be rendered in one draw call. The renderer groups only meshes (static, skinned, etc.) and doesn't group other objects (billboards, grass, etc.).

Transparency Issues

Transparency option in the Common tab of the material enables to create transparent materials for objects. Transparent objects can be rendered in the deferred pass and in the forward.

Option Pass Description Blending to set
Opaque Deferred for opaque objects Used for opaque materials No blending
Alpha blend Forward for transparent objects Standard alpha blending Src = src alpha
Dest = one minus src alpha
Additive Forward for transparent objects Color addition Src = one
Dest = one
Multiply Forward for transparent objects Color multiplication Src = dest color
Dest = zero
Deferred alpha blend Deferred for transparent objects Rendered over opaque materials to the G-buffer, alpha blending is used No blending
Custom Forward for transparent objects Used for custom configurations Custom

Deferred Pass Transparent Objects

Transparent objects in the deferred pass are grouped to be rendered in one draw call. Transparent objects which were rendered in deferred pass overlap other transparent objects that were rendered in deferred pass.

Deferred transparent objects provide realistic reflections and it covers almost 75% of cases when you need a transparent object.

Notice
To use reflections from reflection probes on transparent objects, you should use deferred pass for transparent objects.

Two transparent objects, rendered in deferred pass.

When the transparent option is enabled, the number of draw calls for light sources will be doubled.

If the Alpha test option of the material enabled, the renderer doesn't group meshes in one draw call (and the number of draw calls will be increased), because Alpha test adds a pre-pass where the depth buffer is rendered one more time.

Deferred transparency is better to use when you have a lot of transparent objects or a high-poly transparent models. In other cases, there's no difference in using deferred or forward transparency.

Forward Pass Transparent Objects

Forward rendering pass is available only for transparent objects. To activate the forward pass, specify the Transparency option according to the table in the common tab of the material and disable deferred transparent pass in the States tab of the material.

Transparent objects are rendered in a single forward pass.

Notice
To use reflections from reflection probes on transparent objects, you should use deferred pass for transparent objects.

Unlike in deferred pass, transparent objects that rendered in forward pass aren't grouped, and the number of draw call increases but it enables the sorting of transparent objects. It increases performance costs, but allows you to see another transparent object behind the first (nearest) transparent object.

Two transparent objects, rendered in forward pass.
Last update: 2017-07-03