.. include:: ../macros.hrst
.. include:: ../abbreviations.hrst

.. _chapter:Light inspector:

Light Inspector
###############

The ``Light Inspector`` panel in |ParaView| provides a comprehensive interface for managing the
lighting setup in a 3D scene. Lighting enhances depth perception, surface detail, and overall
visualization quality. The ``Light Inspector`` allows you to configure and customize each individual
light source used during rendering. It is especially useful for:

* Fine-tuning visuals for publication or presentation.
* Creating dramatic or realistic lighting environments.
* Enhancing geometric depth and shape perception.
* Highlighting specific features in complex datasets.

To open the ``Light Inspector``, go to the :guilabel:`View` menu and select :guilabel:`Light Inspector`.
The panel displays all lights active in the current view. You can modify or disable the default
lights and create new ones as needed.

By default, |ParaView| uses a ``Light Kit``--a preconfigured set of lights designed to provide
balanced illumination. You can edit or disable the ``Light Kit`` and manually add ``Scene``,
``Camera``, ``Headlight``, or ``Ambient`` lights to create custom lighting setups. Multiple lights
can be active at once, and their effects combine to illuminate the view.

.. figure:: ../images/LightInspectorPanel.png
    :name: fig\:LightInspectorUI
    :width: 60%
    :align: center

    The ``Light Inspector`` panel showing the default Light Kit.

Light Kit
=========

The ``Light Kit`` consists of a set of directional lights that simulate common studio or natural
lighting setups:

* **Key Light**: The primary light source, typically bright and overhead.
* **Fill Light**: Positioned opposite the key light to reduce harsh shadows.
* **Back Lights**: Two weaker lights from behind to improve edge definition.
* **Headlight**: Aligned with the camera to reduce contrast and ensure visibility.

These lights are directional and move with the camera. They are configured using a set of ratios and
angles instead of absolute positions.

The following parameters can be set in the UI:

* ``Light Kit``: Checkbox to toggle all kit lights on or off.
* ``Reset``: Restores all kit lights to their default settings.
* ``Maintain Luminance``: When checked, intensity is adjusted based on perceived color brightness.

Each light in the kit includes configurable parameters:

* ``Warm``: Sets the color of the light along a warmth scale from 0 (cold blue) to 1 (warm red). A value of 0.5 is neutral white.
* ``Int``: The intensity of the key light (0 = off, 1 = full intensity).
* ``K:F``, ``K:B``, ``K:H``: Ratios for key-to-fill, key-to-back, and key-to-headlight intensities. Higher values result in dimmer secondary lights. Recommended ranges are:

  * ``K:F``: 2-10
  * ``K:B``: 2-10
  * ``K:H``: 2-15

* ``Ele (Elevation)`` and ``Azi (Azimuth)``: Define the vertical and horizontal angles of each light relative to the camera's lookat point, defined in degrees. For example:

  * ``(Elevation=90, Azimuth=0)``: directly above the scene.
  * ``(Elevation=0, Azimuth=0)``: at the camera (i.e., a headlight).
  * ``(Elevation=45, Azimuth=-20)``: above and in front, slightly to the left.

The ``Light Kit`` is built on top of the ``vtkLightKit`` class. For further details read
`here <https://vtk.org/doc/nightly/html/classvtkLightKit.html>`_.

Additional Light Sources
========================

In addition to the ``Light Kit``, you can add individual lights to customize view illumination.
Each light source in the ``Light Inspector`` provides the following controls:

* ``Enable``: Toggles the light on/off in the current view.
* ``Coords``: Specifies how the light is positioned relative to the view and its camera:

  * ``Headlight``: Lights the scene from the camera's point of view and moves with it.
  * ``Camera``: Light is attached to the camera but allows for customized direction.
  * ``Scene``: Light is stationary and defined in world coordinates, independent of camera motion.
  * ``Ambient``: Omnidirectional, uniform illumination without shading.

* ``Intensity``: Controls the brightness of the light.
* ``Type``: Defines the emission behavior of the light source.

  * ``Directional``: Light comes from an infinite distance with parallel rays (like sunlight), only direction matters.
  * ``Positional``: Light originates from a specific point in space and spreads outward; both position and direction affect the scene.

* ``Light Position`` and ``Focal Point``: For ``Camera`` and ``Scene`` lights, these define the location of the light and where it is pointing. Their values can be adjusted via the numeric boxes, by dragging the interactive widget in the 3D view, or by clicking the ``Move to Camera`` button to use the current camera position and orientation.
* ``Show Light``: For ``Scene`` lights, this toggles the display of the 3D view widget.
* ``Cone Angle``: For lights where ``Type`` is set to ``Positional`` only. Sets the beam spread in degrees (similar to spotlight width).
* ``Diffuse Color``: Defines the light's color. To edit, click the color swatch to open a color picker.
* ``Radius``: For OSPRay rendering, controls the light size. Measured in degreed when ``Type`` is ``Directional``, and in degrees when ``Type`` is ``Positional``.

To add a new light, click the ``Add Light`` button at the top of the panel. To delete a light, click
its corresponding ``Remove Light`` button. Use the provided combo boxes, sliders, and numeric boxes
to adjust light properties and preview changes in real time in the 3D view.

.. note::

    When configuring lighting, it is important to choose a display representations that supports
    shading, such as ``Surface`` or ``Volume``. Other representations may not show shading clearly
    or not respond to lighting changes, like ``Outline``, ``Wireframe``, or 2D representations
    (e.g., images or plots).

Configuring Lights in ``pvpython``
==================================

All of the ``light kit`` and individual light source settings shown above are also available via
|ParaView|'s Python API. This makes it possible to programmatically define lighting setups,
reproduce renderings, or generate animations with precise control.

The following example shows how to load a dataset, set up the ``Light Kit``, and add two custom
light sources.

We'll use the ``disk_out_ref.ex2`` example dataset that ships with |ParaView|. The following code
segment loads the data and applies proper rendering to allow us to visualize the 3D structure.

.. code-block:: python

  # load the 'disk_out_ref.ex2' example dataset
  disk = ExodusIIReader(FileName=['disk_out_ref.ex2'])
  disk.PointVariables = ['Pres']

  # apply a surface representation of the pressure
  view = GetActiveViewOrCreate('RenderView')
  Show(disk, view)

  display = GetDisplayProperties(disk)
  ColorBy(display, ('POINTS', 'Pres'))

  # adjust the camera angle so we can better see the geometry of the data
  view.CameraPosition = [10, -20, -60]
  view.CameraFocalPoint = [0, 0, 0]
  view.CameraViewUp = [1, 1, 0]
  view.Update()

  Render()

.. figure:: ../images/LightInspectorDiskDefault.png
    :name: fig\:LightInspectorDiskDefaultLighting
    :align: center

    The rendered dataset, illuminated with the default scene lighting.

The ``Light Kit`` is enabled by default, but we can customize its behavior. While the default settings
are generally suitable, we'll explicitly set each option below to demonstrate how the kit can be
tuned for different lighting effects:

.. code-block:: python

  # enable the light kit (on by default)
  view.UseLight = 1

  # adjust key light properties
  view.KeyLightWarmth = 0.6
  view.KeyLightIntensity = 0.75
  view.KeyLightElevation = 50
  view.KeyLightAzimuth = 10

  # adjust fill light properties
  view.FillLightWarmth = 0.4
  view.FillLightKFRatio = 2.5
  view.FillLightElevation = -75
  view.FillLightAzimuth = -10

  # adjust back light properties
  view.BackLightWarmth = 0.5
  view.BackLightKBRatio = 3.5
  view.BackLightElevation = 0
  view.BackLightAzimuth = 110

  # adjust head light properties
  view.HeadLightWarmth = 0.5
  view.HeadLightKHRatio = 2.0

  # disable automatic luminosity (off by default)
  view.MaintainLuminance = 0

  Render()

.. figure:: ../images/LightInspectorDiskWithLightKit.png
    :name: fig\:LightInspectorDiskWithLightKit
    :align: center

    The same data, now visualized with the modified Light Kit configuration.

We'll also add individual custom lights, which behave independently from the ``Light Kit``. We add one
positional light to illuminate the middle of the hollow side of the cylinder, and another directional
light to brighten the side of the cylinder and increase the overall contrast.

.. code-block:: python

  # add a positional scene light shining into the hollow end of the cylinder
  cameraLight = AddLight()
  cameraLight.Coords = 'Scene'
  cameraLight.Intensity = 0.25
  cameraLight.Type = 'Positional'
  cameraLight.Position = [0, 0, -50]
  cameraLight.FocalPoint = [0, 0, 0]
  cameraLight.ConeAngle = 5
  cameraLight.DiffuseColor = [0.9, 0.9, 1.0]  # cool white, in normalized RGB
  cameraLight.Enable = 1  # turn the light source on (on by default upon creation)

  # add a directional scene light from the front-left
  sceneLight = AddLight()
  sceneLight.Coords = 'Scene'
  sceneLight.Intensity = 0.5
  sceneLight.Type = 'Directional'
  sceneLight.Position = [-60, -30, 15]
  sceneLight.FocalPoint = [0, 0, 0]
  sceneLight.DiffuseColor = [1.0, 1.0, 1.0]  # white
  sceneLight.Enable = 1

  Render()

.. figure:: ../images/LightInspectorDiskAllLights.png
    :name: fig\:LightInspectorDiskWithAllLightsOn
    :align: center

    The final visualized data with all lights turned on.

Although subtle in this dataset, the added lighting improves depth perception and makes it easier to
interpret shaded regions, especially inside the hollow half of the cylinder. More complex models
could benefit from even more dramatic effects, depending on the use case and the intent for the
visualization.

If you're preparing screenshots or animations, you may want to hide the visual indicators for lights
in the 3D view:

.. code-block:: python

  # optionally hide the interactive light widgets from the 3D view
  HideInteractiveWidgets(proxy=cameraLight)
  HideInteractiveWidgets(proxy=sceneLight)

To shown them again:

.. code-block:: python

  # show the light widgets again
  ShowInteractiveWidgets(proxy=cameraLight)
  ShowInteractiveWidgets(proxy=sceneLight)

.. figure:: ../images/LightInspectorDiskAllLightsAndWidgets.png
    :name: fig\:LightInspectorDiskWithLightWidgets
    :align: center

    The visualized data shown from a different angle, with the interactive light widgets enabled.
