shown in other instead.
Unigine renderer is fully deferred:
- all opaque (non-transparent) geometry is rendered in the deferred pass
- transparent objects are rendered in the forward pass.
In case of deferred pass, the engine fills the buffer (called G-Buffer, geometry buffer) by using "render to texture" approach. After deferred pass, the transparent objects are rendered in forward pass and added to the final image. Water is rendered to special buffer (called WBuffer) in special water pass and then also added to the final image.
This article introduces the detailed Unigine 2 rendering pipeline including all the auxiliary stages which can be skipped by user.
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.
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.
- Common pass
- Calculating Intersections
- Rendering shadow maps
- Rendering dynamic reflections
- Deferred pass for opaque objects
- Forward pass for transparent objects
- Render Post Materials
- Rendering Shadow Shafts
- Rendering Camera Effects
- Final Screen Composition
- Post Materials
- Rendering Visualizer
- Rendering GUI
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.
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.
The engine creates cascaded shadow maps for the world light sources.
Rectangular shadow cascades.
World Light's shadow map is rendered into orthographic projection.
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.
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.
Shadow maps for Proj light sources are rendered only once, because only 1 camera is used.
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.
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 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):
Engine depth buffer stores compressed depth (the buffer is linear), whilst the native depth buffer is non-linear.
Diffuse colors buffer stores pure diffuse colors of all material textures:
The format of the texture is RGBA8 (RT1):
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):
Specular buffer stores the specular values of objects on the scene.
The format of the texture is RGBA8 (RT3):
Translucency is used to simulate light shine through objects (leaves, for example).
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):
Decal mask buffer contains information about decals.
The format of the texture is R32U (RT5):
Light map buffer is used to add baked light to the scene.
The format of the texture is RGBA16F (RT6):
A channel contains surface ambient occlusion which is baked, ambient occlusion works alongside with it.
Use the render_surface_light_map 0 console command to disable light map rendering (the engine will use only A channel).
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:
The engine simply adds the decals textures on top of the rendered buffers.
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.
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.
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.
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.
Screen-space Ambient Occlusion is rendered in its own texture. It also will be applied on the deferred composite stage.
Screen-space Reflections are rendered in its own texture. It also will be applied on the deferred composite stage.
On this stage the scattering is rendered by using Environment cubemap and LUTs textures that were obtained in the Common pass
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).
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.
During the ambient pass the environment, lightmaps, emission for transparent objects are calculated.
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.
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.
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.
On this stage the engine visualizer is rendered: mesh wireframes, bounding boxes, etc.
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.
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 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.
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.
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.