############
Light Shapes
############


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

    bk_sgo_ls/bk_sg_real_time_lights
    bk_sgo_ls/bk_sg_physical_lights
    bk_sgo_ls/bk_sg_decay_equations


This chapter will try to give you a bright look on the lighting shapes of the HOOPS Luminate scene graph. As all other HOOPS Luminate shapes, the light shape is created using the ``RED::Factory`` and the ``CID_REDLightShape`` identifier. It implements the following interfaces:

+------------------------------+------------------------------------------+
| Interface                    | Description                              |
+==============================+==========================================+
| ``RED::ILightShape``         | General light management API.            |
+------------------------------+------------------------------------------+
| ``RED::IPhysicalLightShape`` | API dedicated to the setup of physically |
|                              | correct light sources.                   |
+------------------------------+------------------------------------------+
| ``RED::ISkyLightShape``      | API used to setup physical skylight      |
|                              | sources.                                 |
+------------------------------+------------------------------------------+
| ``RED::ISunLightShape``      | API used to setup physical sunlight      |
|                              | sources.                                 |
+------------------------------+------------------------------------------+
| ``RED::IShape``              | Global shape API. Controls shape tree    |
|                              | navigation and shape attributes.         |
+------------------------------+------------------------------------------+
| ``RED::IUserData``           | User data API to store application       |
|                              | custom data associated to a shape.       |
+------------------------------+------------------------------------------+
| ``RED::IChunkSaver``         | Shape serialization interface.           |
+------------------------------+------------------------------------------+
| ``RED::IReferenceSolving``   | Shape serialization interface.           |
+------------------------------+------------------------------------------+

A light that is created implements all of the interface above. Therefore, at its creation, it can be used for any purpose. There are two light categories:

	1. Non physically correct lights, also called real-time lights: :doc:`/book/subjects/bk_sgo/bk_sgo_ls/bk_sg_real_time_lights`
	2. Physically correct lights, explained here: :doc:`/book/subjects/bk_sgo/bk_sgo_ls/bk_sg_physical_lights`

While physical lights can only use a quadratic decay equation, non physically correct lights have a variety of possible intensity :doc:`/book/subjects/bk_sgo/bk_sgo_ls/bk_sg_decay_equations`.

As a complete hybrid engine, HOOPS Luminate can run in software or in hardware. Some of the lights detailed in the sub-pages above are dedicated either to software and/or hardware rendering. HOOPS Luminate defines rendering conversions between the different lights, depending on the light and how it gets rendered. See all the details on each light's description page.


**************************
The Axis System of a Light
**************************

All light sources in HOOPS Luminate have an axis system. This axis system can be controlled from the ``RED::ILightShape`` interface, using ``RED::ILightShape::SetPos``, ``RED::ILightShape::SetSight``, ``RED::ILightShape::SetTop`` or ``RED::ILightShape::SetRight``; but most of the time, this is the light construction method that will change the light axis system, when applicable.

The default axis system of a light source is detailed below:

.. figure:: default_light_axis_system.png 
  :align: center
  
  **The default axis system of a light source**


**************************
Positioning a Light Source
**************************

The best way to position a light source is generally not to redefine the light axis system (this can be done, of course), but rather it's to use an intermediate transform shape to position the light source, forming a scene graph:

.. figure:: light_with_node_transform.png 
  :align: center
  
  **Use a transform node as a parent of the light to reposition it.**

The benefit of proceeding this way is about light updates. The light source may store a lot of parameters for the rendering, several of these parameters being highly dependent on the light source definition. Changing the light source to move it will have a greater cost than changing the transformation node above the light source.


***************
Light Layersets
***************

Any light source in HOOPS Luminate supports several layers for the definition of:

	* Shadow casting objects (``RED::ILightShape::SetLayerSetShadowCaster``)
	* Shadow receiving objects (``RED::ILightShape::SetLayerSetShadowReceiver``)
	* Light receiving objects (``RED::ILightShape::SetLayerSetLit``)

Of course, changing any ``RED::LayerSet`` here is highly non physical! This can be used to customize the behavior of the light source in a scene graph. The ``RED::LayerSet`` of the considered property is checked against the ``RED::LayerSet`` of the lit or shadowed object to figure out whether lighting or shadows apply to this object. In the example below:

.. image:: light_layersets.png

We remove one object from one of the layersets in sequence. We see that we can control exactly how the light will behave.


******************
Light Render Modes
******************

The ``RED::RENDER_MODE`` enumeration contains a number of flags that can be set on any light source to control its behavior. A render mode is set using ``RED::ILightShape::SetRenderMode``. The most important render modes are about shadow control and light geometry (for physical lights).


************
Light Baking
************

The list of render modes in a light includes the ``RED::RM_BAKED`` render mode. This mode can be turned on to activate light baking. A baked light is not rendered at all by any of the ``RED::IWindow rendering methods``. It's ignored, except if we record a global illumination cache. In this case, the light's lighting contribution is calculated and stored along with global illumination samples. Then, rendering the cache will restore the light's intensity.

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


***************************
Available Shadowing Methods
***************************

There are three shadow casting methods that can be used by a light source:

.. figure:: shadow_casting_methods.png 
  :align: center
  
  **Example of the three shadow casting methods available in HOOPS Luminate**

A physical light (or a rectangular area light) can cast area shadows. The smoothness and penumbra resulting of these shadows is due to the fact that the light emitting geometry has a surface. This is the case for physical lights, for rectangular area lights, for skylights and for the sunlight. All these light source do produce soft smooth shadows. The observed shadow hardness depends on the visible surface of the light source from the lit point.

Centric or directional light sources (e.g. lights that have no surface) can only cast hard shadows, as illustrated by the middle image above. These lights are producing a non physically correct result, as there's no light in the real world whose emitting surface is reduced to a singular point (or infinite emitting direction).

Finally, HOOPS Luminate also supports shadow mapping for spot lights, beam lights and omni directional lights. Shadow mapping is a well know computer graphics trick using the depth buffer to get a depth above which we're in shadow. Shadow map can be blurry (depending on the filtering applied for them), and are subject to a number of artifacts due to near / far range issues, banding for blurred shadow maps or biasing.

Controlling the shadow casting method is done on a per light basis. Some lights do have a set of available shadow casting methods while others don't. Please refer to the dedicated light sub-pages (:doc:`/book/subjects/bk_sgo/bk_sgo_ls/bk_sg_real_time_lights` and :doc:`/book/subjects/bk_sgo/bk_sgo_ls/bk_sg_physical_lights`) for details.

