Освещение и тени

Освещение в Kepler.gl опирается на возможности underlying-движка deck.gl и WebGL-рендеринга, где визуальная глубина формируется не столько классическими тенями, сколько комбинацией источников света, нормалей геометрии и параметров материалов. В геопространственной визуализации это особенно важно: карта перестаёт быть плоской, а данные начинают восприниматься как объёмные структуры, зависящие от высоты, плотности и интенсивности.

Kepler.gl использует архитектуру deck.gl, в которой освещение задаётся через объект lightingEffect. Он описывает поведение сцены при взаимодействии с источниками света и материалами объектов.

Основная идея заключается в том, что каждый слой (hexagon, grid, column, scatterplot) может иметь собственную реакцию на свет, если он поддерживает 3D-геометрию или высоту.

Ключевым элементом становится вычисление интенсивности освещения на основе нормалей поверхности:

  • нормаль определяет ориентацию поверхности;
  • направление света задаёт вектор освещения;
  • итоговая яркость рассчитывается через скалярное произведение этих векторов.

Визуально это создаёт эффект объёма без явного использования теневых карт.


Источники света: ambient и directional

В Kepler.gl применяется два основных типа освещения:

Ambient light (рассеянный свет) Определяет базовую яркость сцены. Он равномерно влияет на все объекты, исключая абсолютные тени и делая карту читаемой даже в сложных сценах.

import {AmbientLight, DirectionalLight, LightingEffect} from '@deck.gl/core';

const ambientLight = new AmbientLight({
  color: [255, 255, 255],
  intensity: 1.0
});

Directional light (направленный свет) Имитирует солнечный свет. Имеет направление и создаёт градации освещения на 3D-объектах.

const directionalLight = new DirectionalLight({
  color: [255, 255, 255],
  intensity: 1.2,
  direction: [-1, -2, -1]
});

Комбинация этих двух источников создаёт баланс между читаемостью и глубиной.

const lightingEffect = new LightingEffect({
  ambientLight,
  directionalLight
});

Интеграция освещения в Kepler.gl

В Kepler.gl эффекты передаются через конфигурацию визуализации. LightingEffect подключается как часть visState или через кастомный deck.gl overlay.

const deckGlProps = {
  effects: [lightingEffect]
};

В контексте Kepler.gl это влияет на все слои, которые поддерживают освещение, включая:

  • 3D hexagon layers
  • column layers
  • terrain и elevation-based визуализации
  • scatterplot с высотой

Материалы объектов и реакция на свет

Каждый слой имеет параметры материала, которые определяют отражение света:

  • ambient — базовая отражённая составляющая
  • diffuse — рассеянное освещение
  • shininess — степень “глянцевости”
  • specularColor — цвет бликов

Пример настройки материала для колонок:

const material = {
  ambient: 0.35,
  diffuse: 0.6,
  shininess: 32,
  specularColor: [255, 255, 255]
};

Эти параметры особенно заметны в ColumnLayer, где высота формирует визуальные пики, а свет подчёркивает их форму.


Объёмное восприятие данных через освещение

Освещение в Kepler.gl используется не только как декоративный эффект, но и как инструмент восприятия данных.

Высотные слои (hexagon, grid) используют свет для:

  • выделения плотных зон через яркость верхних граней;
  • создания градиентов от основания к вершине;
  • усиления различий между соседними ячейками.

При низком угле направленного света возникает эффект “рельефа”, где данные начинают напоминать горный ландшафт.


Имитация теней и ограничение WebGL

В классическом смысле Kepler.gl не использует shadow mapping. Вместо этого применяются косвенные методы:

  1. Градиент освещения Разница в яркости между верхней и боковой поверхностью.

  2. Окклюзия через плотность данных Более высокие объекты визуально перекрывают менее выраженные.

  3. Depth testing WebGL Обеспечивает правильное наложение объектов по глубине.

  4. Угол источника света Создаёт псевдотени на основе нормалей.

Такой подход значительно легче для GPU и подходит для больших массивов геоданных.


Настройка освещения в сложных сценах

При работе с несколькими слоями важно согласовывать параметры света, чтобы избежать визуального конфликта.

Типичная конфигурация:

const ambientLight = new AmbientLight({
  color: [200, 200, 200],
  intensity: 0.8
});

const directionalLight = new DirectionalLight({
  color: [255, 255, 255],
  intensity: 1.0,
  direction: [-1, -1.5, -0.5]
});

Снижение интенсивности направленного света уменьшает контраст, что полезно при плотных визуализациях, где важно сохранить читаемость.


Влияние освещения на производительность

Освещение в deck.gl реализовано через shader-вычисления, поэтому его стоимость зависит от:

  • количества активных слоёв;
  • сложности геометрии (hexagon > scatterplot);
  • наличия динамических обновлений света;
  • использования нескольких источников.

Directional light требует дополнительных вычислений нормалей и отражения, но остаётся оптимизированным благодаря GPU-параллелизму.


Взаимодействие с 3D трансформациями

При включении наклона карты (pitch) освещение начинает играть ключевую роль. Одни и те же данные могут выглядеть совершенно по-разному в зависимости от:

  • угла обзора камеры;
  • направления directional light;
  • масштаба высотных данных.

Это создаёт эффект динамического рельефа, где карта перестаёт быть статичной.


Практика комбинирования освещения с высотными данными

Для hexagon слоёв освещение усиливает различие между значениями:

  • высокая плотность → яркие, объёмные пики;
  • низкая плотность → плоские, затемнённые области.
const hexLayer = new HexagonLayer({
  id: 'hex',
  data,
  elevationScale: 50,
  extruded: true,
  material: {
    ambient: 0.4,
    diffuse: 0.6,
    shininess: 16
  }
});

Здесь визуальная выразительность достигается не цветом, а взаимодействием света и геометрии.


Роль освещения в пользовательском восприятии геоданных

Световая модель влияет на когнитивную интерпретацию данных:

  • яркие зоны воспринимаются как более значимые;
  • перепады освещения формируют визуальную иерархию;
  • наклон света создаёт направление “чтения” карты.

Даже при одинаковых значениях данных разные настройки освещения могут радикально изменить интерпретацию визуализации.


Тонкая настройка визуального баланса

Баланс между ambient и directional компонентами определяет характер сцены:

  • высокий ambient → равномерная, “плоская” карта;
  • высокий directional → выраженный рельеф;
  • сбалансированное сочетание → читаемый объём без перегрузки контрастом.

Оптимальная настройка зависит от плотности данных и цели визуализации, а не от фиксированных значений.