• Light

Environmental Lighting

By: SKY ENGINE AI
scroll down ↓to find out moreenv-light_7_resourcesTutorial

Environment Lighting

In this section, you will get to know how Environment Lighting works in the SkyRenderer.

Agenda:

  • Environment Lighting theory
  • Internal Lights algorithm
  • Environment Lighting parameters
  • Reflections of procedures

Scene setup

Let's use a custom scene composer to set up the scene.

    from skyrenderer.cases.utils import EnvLightSceneComposer
/home/ws3h/projects/skyrenderer/.venv/lib/python3.12/site-packages/skyrenderer/utils/visualization_helper.py:3: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from tqdm.autonotebook import tqdm

    scene_composer = EnvLightSceneComposer()
    scene_composer.setup_scene()
2025-07-15 12:03:29,475 | skyrenderer.scene.renderer_context |  INFO: Root paths:
- root path: /home/ws3h/projects/skyrenderer/.venv/lib/python3.12/site-packages/skyrenderer
- assets path: /dli/mount/assets
- config path: /home/ws3h/projects/skyrenderer/.venv/lib/python3.12/site-packages/skyrenderer/config
- gpu sources path: /home/ws3h/projects/skyrenderer/.venv/lib/python3.12/site-packages/skyrenderer/optix_sources/sources
- cache path: /dli/mount/cache
- ptx cache path: compiled_ptx/ptx
- ocio path: ocio_configs

2025-07-15 12:03:29,676 | skyalembic.archive_manager |  WARNING: Loading not adapted alembic file

Environment Lighting Theory

An HDR (High Dynamic Range) texture map can be used to illuminate the scene. Setup of a Background with
HDRTextureProvider has been covered by PROVIDER_HDRTextureProvider case. Besides being a background, the HDR map is
used to generate an additional source of lights that illuminate all objects. A huge advantage of illumination with
the HDR map is the fact that source of light complies with values of the HDR map, providing photorealistic results.

    from skyrenderer.basic_types.item_component import Background
    from skyrenderer.basic_types.procedure import EnvMapMiss
    from skyrenderer.basic_types.provider import HdrTextureProvider
    scene_background = Background(
        scene_composer.renderer_context,
        EnvMapMiss(scene_composer.renderer_context),
        HdrTextureProvider(scene_composer.renderer_context, "blaubeuren_church_square"),
    )
    scene_composer.renderer_context.define_env(scene_background)
    scene_composer.visualize()
env-light_1_resourcesTutorial
2025-07-15 12:03:48,256 | skyrenderer.utils.time_measurement |  INFO: Setup time: 18.56 seconds

2025-07-15 12:03:51,646 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.39 seconds

2025-07-15 12:03:53,393 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:03:53,393 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.75 seconds

Internal Lights algorithm

Whole approach with illumination with an HDR texture map relies on the generation of an artificial source of lights named
Internal Lights, in the brightest parts of the HDR map. There is an automatic algorithm implemented in SkyRenderer, which
scans HDR maps searching for potential sources of lights. Then, a particular number of the brightest parts of the
environmental map are chosen and in their place Internal Lights are spawned. Strength and color of the Internal Lights
is based on the HDR map values. By default, the count of internal lights for an .hdr asset is defined by an artist
in the accompanying .json file, but the user can manipulate this value via the HDRTextureProvider. On the above render, the
blaubeuren_church_square HDR used a default value of internal_lights_count of 5. By using only 1 Internal Light, we
use only the strongest one, in this case, the blue light:

    scene_background = Background(
        scene_composer.renderer_context,
        EnvMapMiss(scene_composer.renderer_context),
        HdrTextureProvider(scene_composer.renderer_context, "blaubeuren_church_square", internal_lights_count=1),
    )
    scene_composer.renderer_context.define_env(scene_background)
    scene_composer.visualize()
env-light_2_resourcesTutorial
2025-07-15 12:03:53,947 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:03:53,948 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:03:53,949 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:00,624 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.68 seconds

2025-07-15 12:04:03,914 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.29 seconds

2025-07-15 12:04:05,648 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:04:05,649 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.73 seconds

To see the effect better, i.e., how the different parts of the HDR map "start to illuminate", we will use the scene_composer's
render_internal_lights_grid() method, which will create a grid for the provided list with counts of Internal Lights:

    scene_composer.render_internal_lights_grid([0, 1, 3])
env-light_3_resourcesTutorial
2025-07-15 12:04:06,130 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:04:06,131 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:04:06,132 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:12,798 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.67 seconds

2025-07-15 12:04:16,077 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.28 seconds

2025-07-15 12:04:17,681 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:04:17,682 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.60 seconds

2025-07-15 12:04:17,703 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:04:17,704 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:04:17,704 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:24,245 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.54 seconds

2025-07-15 12:04:27,100 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.85 seconds

2025-07-15 12:04:27,773 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:04:27,774 | skyrenderer.utils.time_measurement |  INFO: Render time: 673 ms

2025-07-15 12:04:27,793 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:04:27,794 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:04:27,795 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:34,460 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.66 seconds

2025-07-15 12:04:37,725 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.26 seconds

2025-07-15 12:04:38,415 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:04:38,416 | skyrenderer.utils.time_measurement |  INFO: Render time: 690 ms

Environment Lighting parameters

In HDRTextureProvider three parameters influence how light affects the scene:

  • gamma_light - power in gamma correction step for environmental light map.
  • intensity_light - final modification of overall HDR intensity used in the light map creation.
  • internal_lights_count - maximum number of internal lights being extracted from HDR. If None, the .json value is used.

We have described above how internal_lights_count parameter works - it defines how many light sources will be
used out of a HDR map. Then, a separate "light_map" is created out of the HDR map consisting only of light sources
and this map is used to spawn Internal Lights with particular parameters. However, prior these lights are spawned,
two parameters - gamma_light and intensity_light can be used to tweak light. It can be also done via the
HDRTextureProvider:

    scene_background = Background(
        scene_composer.renderer_context,
        EnvMapMiss(scene_composer.renderer_context),
        HdrTextureProvider(scene_composer.renderer_context, "blaubeuren_church_square", gamma_light=2.4),
    )
    scene_composer.renderer_context.define_env(scene_background)
    scene_composer.visualize()
env-light_4_resourcesTutorial
2025-07-15 12:04:38,616 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:04:38,618 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:04:38,618 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:45,185 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.57 seconds

2025-07-15 12:04:48,472 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.29 seconds

2025-07-15 12:04:50,301 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:04:50,302 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.83 seconds

    scene_background = Background(
        scene_composer.renderer_context,
        EnvMapMiss(scene_composer.renderer_context),
        HdrTextureProvider(
            scene_composer.renderer_context, "blaubeuren_church_square", gamma_light=2.4, intensity_light=3
        ),
    )
    scene_composer.renderer_context.define_env(scene_background)
    scene_composer.visualize()
env-light_5_resourcesTutorial
2025-07-15 12:04:50,783 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:04:50,784 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:04:50,785 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:04:57,470 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.68 seconds

2025-07-15 12:05:00,738 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.27 seconds

2025-07-15 12:05:02,568 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:02,568 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.83 seconds

Reflections of procedures

It is not related directly to the Environment Lighting, however we have to remember that some of the shading procedures use
HDR maps to reflect colors of the environment map:

    from skyrenderer.basic_types.procedure import PBRShader
    PBRShader.update_default_parameter("use_reflections", True)
    scene_composer.render_internal_lights_grid([0, 1, 3])
env-light_6_resourcesTutorial
2025-07-15 12:05:03,052 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:03,054 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:03,054 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:05:09,599 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.54 seconds

2025-07-15 12:05:12,603 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.00 seconds

2025-07-15 12:05:14,359 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:14,360 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.76 seconds

2025-07-15 12:05:14,382 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:14,383 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:14,384 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:05:21,295 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.91 seconds

2025-07-15 12:05:24,139 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.84 seconds

2025-07-15 12:05:25,081 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:25,082 | skyrenderer.utils.time_measurement |  INFO: Render time: 943 ms

2025-07-15 12:05:25,109 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:25,110 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:25,110 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:05:31,776 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.66 seconds

2025-07-15 12:05:34,644 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.87 seconds

2025-07-15 12:05:36,660 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:36,661 | skyrenderer.utils.time_measurement |  INFO: Render time: 2.02 seconds

In a case when the HDR map has only a few pixels that have extremely high values, compared to the rest of the map, we can
modify the value of the max_hdr_value parameter in EnvMapMiss, as shown in the PROVIDER_HDRTextureProvider case. This will
cause a clamp of color reflections on the scene, so the render will not be grainy for lower number of samples:

    scene_composer.render_internal_lights_grid([0, 1, 3], max_hdr_value=5)
env-light_7_resourcesTutorial
2025-07-15 12:05:36,874 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:36,875 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:36,876 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:05:43,655 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.78 seconds

2025-07-15 12:05:46,531 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.88 seconds

2025-07-15 12:05:47,281 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:47,282 | skyrenderer.utils.time_measurement |  INFO: Render time: 751 ms

2025-07-15 12:05:47,295 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:47,296 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:47,297 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:05:53,867 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.57 seconds

2025-07-15 12:05:56,738 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.87 seconds

2025-07-15 12:05:57,683 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:05:57,684 | skyrenderer.utils.time_measurement |  INFO: Render time: 946 ms

2025-07-15 12:05:57,697 | skyrenderer.basic_types.provider.iprovider |  WARNING: Provider for this config has been already initialized! There should be just one Provider created per unit source, consider fixing the scene.
Config:
blaubeuren_church_square

2025-07-15 12:05:57,698 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-07-15 12:05:57,698 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-07-15 12:06:04,370 | skyrenderer.utils.time_measurement |  INFO: Setup time: 6.67 seconds

2025-07-15 12:06:07,224 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.85 seconds

2025-07-15 12:06:08,238 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-07-15 12:06:08,239 | skyrenderer.utils.time_measurement |  INFO: Render time: 1.01 seconds

Summary

In this section you have learnt:

  • HDR maps can be used to illuminate the scene.
  • In the brightest parts of the map, Internal Lights are spawned based on the provided count in .json or manually.
  • Some procedures can cause objects to be grainy, due to small areas of high value pixels on the HDR map. This
    can be fixed by using the max_hdr_value in the EnvMapMiss ParameterProvider.