Освещение играет важную роль при визуализации трёхмерных объектов на карте. Без корректной настройки источников света объекты выглядят плоскими, теряют глубину и становятся сложнее для восприятия. Одним из наиболее важных типов освещения в Deck.gl является Directional Light — направленный источник света, имитирующий удалённый объект наподобие Солнца.
В отличие от точечных источников света, которые имеют конкретное положение в пространстве, направленный свет определяется только направлением распространения лучей. Все лучи считаются параллельными друг другу, что соответствует физической модели освещения от очень удалённого источника.
Наиболее часто Directional Light применяется для:
PolygonLayer;ScenegraphLayer;Система освещения реализована через набор специальных классов из пакета:
import {
AmbientLight,
DirectionalLight,
LightingEffect
} from '@deck.gl/core';
Основные типы освещения:
| Тип | Назначение |
|---|---|
| AmbientLight | Равномерное фоновое освещение |
| DirectionalLight | Направленный свет |
| PointLight | Точечный источник света |
| CameraLight | Свет от камеры |
В большинстве проектов используется комбинация:
AmbientLight + DirectionalLight
Такое сочетание обеспечивает хорошую детализацию поверхностей без чрезмерного затемнения.
Создание направленного источника света выполняется через класс
DirectionalLight.
Базовый пример:
import {DirectionalLight} from '@deck.gl/core';
const sunlight = new DirectionalLight({
color: [255, 255, 255],
intensity: 1.0,
direction: [-1, -3, -1]
});
Параметры конструктора определяют свойства света и его влияние на сцену.
Самая важная характеристика направленного света — направление лучей.
Пример:
direction: [-1, -3, -1]
Вектор показывает направление распространения света.
Компоненты:
[x, y, z]
где:
x — направление по оси восток-запад;y — направление по оси север-юг;z — направление по вертикали.Пример освещения сверху:
direction: [0, 0, -1]
Свет падает строго вниз.
Освещение под углом:
direction: [-1, -2, -1]
Освещение почти горизонтально:
direction: [-5, -1, -0.2]
При небольшом значении Z образуются длинные тени, напоминающие утреннее или вечернее солнце.
Длина вектора направления не имеет значения.
Следующие варианты эквивалентны:
direction: [-1, -1, -1]
direction: [-10, -10, -10]
direction: [-100, -100, -100]
Внутри движка выполняется нормализация:
v = v / |v|
Поэтому важно только соотношение координат.
Определяет цвет света.
Белый источник:
color: [255, 255, 255]
Тёплое солнечное освещение:
color: [255, 240, 210]
Закатный свет:
color: [255, 180, 120]
Холодное освещение:
color: [180, 220, 255]
Пример:
const sunlight = new DirectionalLight({
color: [255, 230, 180],
intensity: 1.2,
direction: [-1, -2, -1]
});
Такая конфигурация визуально напоминает освещение в вечернее время.
Управляет яркостью источника света.
Пример:
intensity: 1.0
Допустимы любые положительные значения.
Слабый свет:
intensity: 0.3
Средний:
intensity: 1.0
Яркий:
intensity: 2.5
Очень яркий:
intensity: 5.0
Пример:
const sunlight = new DirectionalLight({
direction: [-1, -3, -1],
intensity: 2.0
});
Слишком большие значения могут приводить к пересвету объектов.
Отдельный источник света не влияет на сцену автоматически.
Сначала создаётся объект эффекта:
const lightingEffect = new LightingEffect({
sunlight
});
Затем он передаётся в Deck:
new Deck({
effects: [lightingEffect]
});
Полный пример:
const sunlight = new DirectionalLight({
color: [255, 255, 255],
intensity: 1.0,
direction: [-1, -3, -1]
});
const lightingEffect = new LightingEffect({
sunlight
});
new Deck({
effects: [lightingEffect]
});
Использование только направленного света редко даёт хороший результат.
Часть объектов оказывается полностью чёрной.
Поэтому обычно добавляется фоновое освещение:
const ambientLight = new AmbientLight({
color: [255, 255, 255],
intensity: 0.4
});
И направленный свет:
const sunlight = new DirectionalLight({
color: [255, 255, 255],
intensity: 1.0,
direction: [-1, -3, -1]
});
Создание эффекта:
const lightingEffect = new LightingEffect({
ambientLight,
sunlight
});
Такая схема наиболее распространена в производственных проектах.
Directional Light особенно важен при использовании экструзий.
Пример слоя:
new PolygonLayer({
id: 'buildings',
data,
extruded: true,
getElevation: d => d.height,
getFillColor: [80, 120, 200]
});
Без освещения:
С Directional Light:
Предположим, имеется группа высотных зданий.
Свет сверху:
direction: [0, 0, -1]
Результат:
Свет сбоку:
direction: [-1, -1, -0.5]
Результат:
Низкий угол:
direction: [-2, -4, -0.2]
Результат:
Deck.gl позволяет создавать несколько источников.
Пример:
const sun = new DirectionalLight({
direction: [-1, -2, -1],
intensity: 1
});
const fill = new DirectionalLight({
direction: [1, 1, -0.5],
intensity: 0.3
});
Подключение:
const lightingEffect = new LightingEffect({
sun,
fill
});
Подобная схема широко применяется в компьютерной графике.
Первый источник формирует основное освещение.
Второй источник смягчает слишком тёмные участки.
Directional Light поддерживает генерацию теней.
Пример:
const sunlight = new DirectionalLight({
direction: [-1, -3, -1],
intensity: 1
});
При использовании механизма shadow mapping свет становится источником теней для объектов сцены.
Тени позволяют:
Для работы теней используются дополнительные настройки.
Пример:
const sunlight = new DirectionalLight({
direction: [-1, -3, -1],
intensity: 1,
shadow: true
});
После включения:
shadow: true
источник начинает участвовать в расчёте теневых карт.
Наиболее естественная модель освещения карты выглядит следующим образом:
const sunlight = new DirectionalLight({
color: [255, 245, 230],
intensity: 1.2,
direction: [-1, -3, -1]
});
Такая конфигурация напоминает дневное солнце.
Для заката:
const sunset = new DirectionalLight({
color: [255, 180, 120],
intensity: 0.8,
direction: [-2, -4, -0.2]
});
Для пасмурной погоды:
const cloudy = new DirectionalLight({
color: [220, 230, 255],
intensity: 0.6,
direction: [-1, -1, -1]
});
Трёхмерные модели особенно сильно зависят от настроек освещения.
Пример:
new ScenegraphLayer({
id: 'cars',
data,
scenegraph: '/models/car.glb',
getPosition: d => d.coordinates
});
При отсутствии Directional Light:
С корректным освещением:
Сам расчёт направленного света требует относительно небольших ресурсов.
Основные затраты связаны с:
Обычное освещение:
DirectionalLight + AmbientLight
практически не влияет на производительность современных видеокарт.
Наиболее затратной операцией является:
shadow: true
особенно при большом количестве объектов на сцене.
Часто используется следующая схема:
const ambientLight = new AmbientLight({
intensity: 0.35
});
const sunlight = new DirectionalLight({
color: [255, 245, 230],
intensity: 1.2,
direction: [-1, -3, -1]
});
const lightingEffect = new LightingEffect({
ambientLight,
sunlight
});
Особенности такой конфигурации: