##################################
Real-Time Rendering of 3D Datasets
##################################

.. toctree::
    :maxdepth: 1
    :titlesonly:
    :hidden:

    bk_re_rrd/bk_re_shadow_mapping_detailed
    bk_re_rrd/bk_re_advanced_shadows_in_real_time


Real-time rendering of 3D data is one of the main task you'll certainly wish to achieve using HOOPS Luminate. HOOPS Luminate can deliver very good performances on very large assemblies. However, a few guidelines should be observed in order to reach an optimal display solution for your need.


***********************
Real-Time or Real-Time?
***********************

A first important thing that we must be aware of: what kind of real-time display are we referring to? A 'real-time' application can be one of these:

  * A viewport display in a CAD or design application
  * A video game display
  * A simulation engine display

Each application can call itself as performing 'real-time' display. However, the FPS - the number of frames displayed per second - can greatly vary. A typical CAD or design application viewport can display data from 5 FPS to 30 FPS. A video game will typically try to keep a 30+ FPS on screen while a simulation engine can't display anything below 60 FPS.

So the type of real-time application is important. The application rendering performance needs and flexibility can drive the choice for one or another way of using HOOPS Luminate. Let's review two major categories of applications:

+-------------------+---------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
| Application Type  | Threading Architecture                                                                      | Shading Model                                                       |
+===================+=============================================================================================+=====================================================================+
| CAD / Design      | :doc:`/book/subjects/bk_ba/bk_ba_tm/bk_ba_single_threaded_graphic_applications`             | :doc:`/book/subjects/bk_bm/bk_bm_using_built_in_luminate_materials` |
+-------------------+---------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
| Game / Simulation | :doc:`/book/subjects/bk_ba/bk_ba_tm/bk_ba_multi_threaded_performance_critical_applications` | :doc:`/book/subjects/bk_bm/bk_bm_writing_a_custom_material`         |
+-------------------+---------------------------------------------------------------------------------------------+---------------------------------------------------------------------+

A typical CAD / Design application needs flexibility: the set of lights is dynamically chosen by the user. Unlike in a video game or simulation environment, data are not constrained: models can be of any size, and the visualization of one model may completely differ from another one in size, number of lights and materials. That's why the resulting performance can vary a lot. Among all flexibility needs, we have a great need for a customizable lighting pipeline. Therefore, using HOOPS Luminate built-in materials and shaders is a great time saver, as these are dynamically adapting to the lighting environment.

On the other hand, a performance critical application like a simulation engine requires a single-pass custom shading system: the application may not be capable of paying the price of extra rendering passes for each light to consider. In this case, using materials with application specific shaders may be the best solution to ensure that the number of rendering passes remain as low as possible for the application needs.

This leads us to considering the number of rendering passes involved in the computation of a frame:


*****************************
Accumulating Rendering Passes
*****************************

The number of rendering passes can be approximatively determined. Basically, we'll count each time we have a viewpoint to draw in a VRL, and for each viewpoint, we'll count the number of passes initiated by the data being rendered: 

  * Count 1 for a shader in the ``RED::MTL_PRELIT`` pass of materials.
  * Count 1 for each light present in the scene for a shader in the ``RED::MTL_LIT`` pass of materials.
  * Count 1 for a shadow map generation (count 2 if shadow map auto range is enabled).
  * Count 1 for a shader the ``RED::MTL_POSTLIT`` pass of materials.
  * Count 'n' for the rendering of transparent objects, where 'n' is the ``RED::OPTIONS_RAY_TRANSPARENCY`` value.
  * Multiply material passes count by 2 for a double sided material rendering.

This is for one ``RED::RenderShader`` in pre-lighting, one in lighting and one in post-lighting. If a material uses two ``RED::RenderShader`` instances in a material rendering pass count 2 for that pass instead of 1. Then, the price of a single rendering pass need to be modulated by the efficiency of culling techniques involved for that pass (frustum culling, light culling, custom callbacks culling, ...)

In addition to this we need to count the pipeline implicit passes, that are mostly screen sized texture copy or shading operations.

  * Count 1 for each render image that needs to be generated (see ``RED::IImage2D::SetRenderImage``)
  * Count 0 for a built-in VRL render image accessed directly (see ``RED::IViewpointRenderList::GetRenderImage``)

Then,

  * Count 1 rendering pass plus 1 texture copy for each rendering pass for each ``RED::IImageComposite`` image used by a shader. A composite image is a screen sized generated texture image, so its contents are defined by a rendering pass.
  * Count 6 for each automatic cube map that has to be generated!

And finally, take anti-aliasing into consideration:

  * Hardware anti-aliasing does not generate extra rendering passes (at least not at the application level)
  * Engine anti-aliasing at level 'n' multiplies everything by n*n (one complete draw for each image tile) if super-scaling is turned off
  * Engine anti-aliasing at level 'n' just adds a screen sized downsize pass if super-scaling is turned on

And last, GPU tone-mapping:

* Adds one screen sized pass

So as a total, the application will render a number of passes drawing geometries and the engine may need to copy (or to apply shaders) a pass results into textures that can be accessed later on during the rendering of the same frame. Depending on the rendered window size, and of course on the application data, screen copy / shading time may be significant or not compared to the real rendering. On non performance critical applications for applications with simple pipelines, this time is generally low enough to be ignored.

Then, the scope of a rendering pass may be determinant in the cost of that pass: for instance the cost of rendering transparent objects may be small if there are almost no transparent objects to handle compared to opaque ones.


************************************************
Choosing between Dynamic Lights and Baked Lights
************************************************

As we have seen, the number of rendering passes involved in the processing of a single frame can be quite high. A large set of light sources can slow down the system a lot, due to the extra rendering passes caused by these lights. It's possible to bake lights. A baked light is not rendered at all during the processing of the frame. It's contribution is stored as a pre-processing phase while computing a global illumination cache.

Please refer to the :doc:`/tutorials/workflows/wf_realtime/wf_gi_and_light_baking` tutorial for details on light baking.


**************************************
Choosing a Full HDR Rendering Pipeline
**************************************

From the :doc:`/book/subjects/bk_ba/bk_ba_hp/bk_ba_gpu_functional_level` matrix, we can see that all of today's GPU have a built-in support for a full HDR rendering pipeline. Therefore, and due to the fact that HOOPS Luminate delivers all the tools needed to render physically correct scenes, turning on HDR is a must have to any application that aim at getting a strong grip on image quality.

.. include:: /tasks/ta_ca/ta_ca_rendering/tk_setting_up_a_hdr_rendering_pipeline.rst


**************
Shadow Mapping
**************

The current technology that deliver the best performance for shadowing is shadow mapping. HOOPS Luminate supports a variety of other shadowing techniques, but for a true real-time (30+ FPS) appplication, shadow maps remain the best choice to get dynamic shadows at a small rendering cost. 

We'll review all shadow mapping details here: :doc:`/book/subjects/bk_re/bk_re_rrd/bk_re_shadow_mapping_detailed`.


**************************
Advanced Real-Time Shadows
**************************

Maybe the world 'real-time' is a bit exaggerated here ;-) HOOPS Luminate's real-time engine and hardware accelerated ray-tracing engine can generate two other types of shadows that can be enabled in a real-time environment:

  * Hard ray-traced shadows that result of the activation of the ``RED::OPTIONS_RAY_SHADOWS`` option, used in a ``RED::IWindow::FrameDrawing`` call.
  * Soft ray-traced shadows that result of using shadow casting with a rectangular area light or with a skylight.

See all the details here: :doc:`/book/subjects/bk_re/bk_re_rrd/bk_re_advanced_shadows_in_real_time`


