Точечное освещение (Point Lighting) представляет собой модель освещения, в которой источник света располагается в конкретной точке трёхмерного пространства и распространяет свет во всех направлениях. Такой подход позволяет реалистично подсвечивать объекты сцены, формировать объём, создавать блики и подчёркивать пространственную структуру геоданных.
В экосистеме Deck.gl точечное освещение используется совместно с системой эффектов и применяется к слоям, поддерживающим расчёт освещения на уровне вершин или фрагментов. Наиболее заметно влияние Point Light проявляется в слоях, содержащих экструдированную геометрию:
Освещение рассчитывается на стороне GPU посредством шейдеров библиотеки luma.gl, которая является графической основой Deck.gl.
Система освещения состоит из нескольких компонентов:
Типичная схема выглядит следующим образом:
import {AmbientLight, PointLight, LightingEffect} from '@deck.gl/core';
Источник света описывает характеристики излучения.
Материал определяет реакцию поверхности на падающий свет.
Эффект объединяет все источники света и передаёт их в рендеринговый конвейер.
Основным объектом точечного освещения является класс
PointLight.
Создание источника света:
import {PointLight} from '@deck.gl/core';
const pointLight = new PointLight({
color: [255, 255, 255],
intensity: 2.0,
position: [-122.4, 37.74, 8000]
});
Основные параметры:
| Параметр | Описание |
|---|---|
| position | Координаты источника света |
| color | Цвет освещения |
| intensity | Интенсивность света |
Параметр position определяет местоположение источника в
мировом пространстве.
Пример:
position: [-122.4, 37.74, 8000]
Значения интерпретируются как:
[longitude, latitude, altitude]
где:
Источник света может находиться:
Изменение позиции оказывает существенное влияние на визуальный результат.
Точечный источник может излучать свет любого цвета.
Белый свет:
color: [255, 255, 255]
Красный свет:
color: [255, 0, 0]
Синий свет:
color: [0, 0, 255]
Тёплый оттенок:
color: [255, 220, 180]
Холодный оттенок:
color: [180, 220, 255]
Цвет света влияет на итоговый цвет поверхности после смешивания с базовым цветом материала.
Параметр intensity определяет силу воздействия
источника.
Низкая интенсивность:
intensity: 0.5
Средняя:
intensity: 1.0
Высокая:
intensity: 3.0
Очень высокая:
intensity: 10.0
При больших значениях возможно появление пересвеченных областей.
Источники света сами по себе не участвуют в рендеринге. Они должны быть зарегистрированы внутри эффекта освещения.
Пример:
import {
AmbientLight,
PointLight,
LightingEffect
} from '@deck.gl/core';
const ambientLight = new AmbientLight({
color: [255, 255, 255],
intensity: 1.0
});
const pointLight = new PointLight({
color: [255, 255, 255],
intensity: 2.0,
position: [-122.4, 37.74, 8000]
});
const lightingEffect = new LightingEffect({
ambientLight,
pointLight
});
После этого эффект подключается к экземпляру Deck.
new Deck({
effects: [lightingEffect]
});
Практически всегда точечное освещение используется совместно с окружающим освещением.
Окружающий свет выполняет роль фоновой подсветки сцены.
Схема работы:
Ambient Light
+
Point Light
=
Итоговое освещение
Без Ambient Light тени могут становиться полностью чёрными, что выглядит неестественно.
Пример:
const ambientLight = new AmbientLight({
intensity: 0.8
});
const pointLight = new PointLight({
intensity: 2.0,
position: [-122.4, 37.74, 8000]
});
Одним из наиболее наглядных примеров является ColumnLayer.
import {ColumnLayer} from '@deck.gl/layers';
Создание слоя:
const layer = new ColumnLayer({
id: 'columns',
data,
diskResolution: 24,
radius: 200,
extruded: true,
getPosition: d => d.coordinates,
getElevation: d => d.value,
getFillColor: [0, 140, 255]
});
При наличии Point Light цилиндры начинают демонстрировать:
Это создаёт ощущение объёма.
Экструдированные полигоны также активно используют освещение.
const polygonLayer = new PolygonLayer({
id: 'buildings',
data,
extruded: true,
getPolygon: d => d.polygon,
getElevation: d => d.height,
getFillColor: [100, 140, 255]
});
При изменении положения источника становятся заметны:
Deck.gl использует объект material для описания свойств
поверхности.
Пример:
material: {
ambient: 0.4,
diffuse: 0.6,
shininess: 32,
specularColor: [255, 255, 255]
}
Каждый параметр влияет на взаимодействие света с поверхностью.
Параметр:
ambient
определяет влияние окружающего освещения.
Пример:
material: {
ambient: 0.2
}
Поверхность становится более контрастной.
Увеличение значения:
material: {
ambient: 1.0
}
делает объект более равномерно освещённым.
Параметр:
diffuse
определяет рассеянное отражение света.
Пример:
material: {
diffuse: 0.8
}
Высокое значение подчёркивает объём объектов.
Низкое значение:
material: {
diffuse: 0.1
}
делает влияние точечного света менее заметным.
Зеркальная составляющая отвечает за блики.
Настройка:
material: {
specularColor: [255, 255, 255]
}
Белые блики характерны для:
Цвет блика можно изменить:
material: {
specularColor: [255, 200, 150]
}
Параметр определяет концентрацию блика.
Низкое значение:
shininess: 4
Широкий и мягкий блик.
Среднее:
shininess: 32
Типичное значение для большинства сцен.
Высокое:
shininess: 128
Очень маленький и яркий блик.
Сцена может содержать несколько Point Light одновременно.
Пример:
const light1 = new PointLight({
color: [255, 255, 255],
intensity: 2,
position: [-122.4, 37.7, 8000]
});
const light2 = new PointLight({
color: [255, 100, 100],
intensity: 1.5,
position: [-122.5, 37.8, 6000]
});
const effect = new LightingEffect({
light1,
light2
});
Такой подход позволяет создавать:
Каждый источник может иметь собственный цвет.
Пример:
const redLight = new PointLight({
color: [255, 0, 0],
intensity: 1.5,
position: [-122.4, 37.7, 7000]
});
const blueLight = new PointLight({
color: [0, 0, 255],
intensity: 1.5,
position: [-122.3, 37.8, 7000]
});
В местах пересечения световых потоков происходит смешивание цветов.
Результатом становятся сложные световые переходы и цветовые градиенты.
Положение Point Light может изменяться в реальном времени.
Пример:
const light = new PointLight({
color: [255, 255, 255],
intensity: 2
});
function updateLight(time) {
light.position = [
-122.4 + Math.sin(time) * 0.1,
37.74,
8000
];
}
Подобный подход используется для:
Высота существенно влияет на распределение света.
Низкое положение:
position: [-122.4, 37.74, 500]
Создаёт выраженные контрасты и боковое освещение.
Средняя высота:
position: [-122.4, 37.74, 5000]
Даёт сбалансированный результат.
Высокое расположение:
position: [-122.4, 37.74, 30000]
Приближает освещение к солнечному типу.
Точечное освещение требует дополнительных вычислений на GPU.
На производительность влияют:
Рекомендуемые практики:
Типичные проблемы при работе с Point Light:
Причины:
LightingEffect;Проверка:
intensity: 5
Причины:
diffuse;Решение:
material: {
diffuse: 0.8
}
Причины:
shininess;specularColor;Проверка:
material: {
shininess: 64,
specularColor: [255, 255, 255]
}
import Deck from '@deck.gl/core';
import {
AmbientLight,
PointLight,
LightingEffect
} from '@deck.gl/core';
const ambientLight = new AmbientLight({
color: [255, 255, 255],
intensity: 0.8
});
const pointLight = new PointLight({
color: [255, 255, 255],
intensity: 2.5,
position: [-122.4, 37.74, 8000]
});
const lightingEffect = new LightingEffect({
ambientLight,
pointLight
});
new Deck({
initialViewState,
controller: true,
effects: [lightingEffect],
layers: [layer]
});
Такая конфигурация обеспечивает сбалансированное освещение сцены, подчёркивает объём экструдированных объектов, формирует естественные светотеневые переходы и позволяет эффективно визуализировать пространственные данные в трёхмерных приложениях на базе Deck.gl.