Освещение в Kepler.gl опирается на возможности underlying-движка deck.gl и WebGL-рендеринга, где визуальная глубина формируется не столько классическими тенями, сколько комбинацией источников света, нормалей геометрии и параметров материалов. В геопространственной визуализации это особенно важно: карта перестаёт быть плоской, а данные начинают восприниматься как объёмные структуры, зависящие от высоты, плотности и интенсивности.
Kepler.gl использует архитектуру deck.gl, в которой освещение
задаётся через объект lightingEffect. Он описывает
поведение сцены при взаимодействии с источниками света и материалами
объектов.
Основная идея заключается в том, что каждый слой (hexagon, grid, column, scatterplot) может иметь собственную реакцию на свет, если он поддерживает 3D-геометрию или высоту.
Ключевым элементом становится вычисление интенсивности освещения на основе нормалей поверхности:
Визуально это создаёт эффект объёма без явного использования теневых карт.
В 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 эффекты передаются через конфигурацию визуализации.
LightingEffect подключается как часть visState или через
кастомный deck.gl overlay.
const deckGlProps = {
effects: [lightingEffect]
};
В контексте Kepler.gl это влияет на все слои, которые поддерживают освещение, включая:
Каждый слой имеет параметры материала, которые определяют отражение света:
Пример настройки материала для колонок:
const material = {
ambient: 0.35,
diffuse: 0.6,
shininess: 32,
specularColor: [255, 255, 255]
};
Эти параметры особенно заметны в ColumnLayer, где высота
формирует визуальные пики, а свет подчёркивает их форму.
Освещение в Kepler.gl используется не только как декоративный эффект, но и как инструмент восприятия данных.
Высотные слои (hexagon, grid) используют свет для:
При низком угле направленного света возникает эффект “рельефа”, где данные начинают напоминать горный ландшафт.
В классическом смысле Kepler.gl не использует shadow mapping. Вместо этого применяются косвенные методы:
Градиент освещения Разница в яркости между верхней и боковой поверхностью.
Окклюзия через плотность данных Более высокие объекты визуально перекрывают менее выраженные.
Depth testing WebGL Обеспечивает правильное наложение объектов по глубине.
Угол источника света Создаёт псевдотени на основе нормалей.
Такой подход значительно легче для 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-вычисления, поэтому его стоимость зависит от:
Directional light требует дополнительных вычислений нормалей и отражения, но остаётся оптимизированным благодаря GPU-параллелизму.
При включении наклона карты (pitch) освещение начинает играть ключевую роль. Одни и те же данные могут выглядеть совершенно по-разному в зависимости от:
Это создаёт эффект динамического рельефа, где карта перестаёт быть статичной.
Для hexagon слоёв освещение усиливает различие между значениями:
const hexLayer = new HexagonLayer({
id: 'hex',
data,
elevationScale: 50,
extruded: true,
material: {
ambient: 0.4,
diffuse: 0.6,
shininess: 16
}
});
Здесь визуальная выразительность достигается не цветом, а взаимодействием света и геометрии.
Световая модель влияет на когнитивную интерпретацию данных:
Даже при одинаковых значениях данных разные настройки освещения могут радикально изменить интерпретацию визуализации.
Баланс между ambient и directional компонентами определяет характер сцены:
Оптимальная настройка зависит от плотности данных и цели визуализации, а не от фиксированных значений.