Point освещение

Точечное освещение (Point Lighting) представляет собой модель освещения, в которой источник света располагается в конкретной точке трёхмерного пространства и распространяет свет во всех направлениях. Такой подход позволяет реалистично подсвечивать объекты сцены, формировать объём, создавать блики и подчёркивать пространственную структуру геоданных.

В экосистеме Deck.gl точечное освещение используется совместно с системой эффектов и применяется к слоям, поддерживающим расчёт освещения на уровне вершин или фрагментов. Наиболее заметно влияние Point Light проявляется в слоях, содержащих экструдированную геометрию:

  • ColumnLayer;
  • PolygonLayer с экструдированием;
  • GeoJsonLayer с трёхмерными полигонами;
  • HexagonLayer;
  • GridLayer;
  • ScenegraphLayer;
  • SimpleMeshLayer;
  • Tile3DLayer.

Освещение рассчитывается на стороне GPU посредством шейдеров библиотеки luma.gl, которая является графической основой Deck.gl.


Архитектура системы освещения

Система освещения состоит из нескольких компонентов:

  1. Источники света.
  2. Материалы объектов.
  3. Эффекты сцены.
  4. Шейдерные вычисления.

Типичная схема выглядит следующим образом:

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

Источник света описывает характеристики излучения.

Материал определяет реакцию поверхности на падающий свет.

Эффект объединяет все источники света и передаёт их в рендеринговый конвейер.


Класс PointLight

Основным объектом точечного освещения является класс 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]

где:

  • 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

При больших значениях возможно появление пересвеченных областей.


Создание LightingEffect

Источники света сами по себе не участвуют в рендеринге. Они должны быть зарегистрированы внутри эффекта освещения.

Пример:

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]
});

Комбинирование Point Light и Ambient Light

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

Окружающий свет выполняет роль фоновой подсветки сцены.

Схема работы:

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

Одним из наиболее наглядных примеров является 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 цилиндры начинают демонстрировать:

  • освещённую сторону;
  • затенённую сторону;
  • плавный переход между ними;
  • блики.

Это создаёт ощущение объёма.


Использование с PolygonLayer

Экструдированные полигоны также активно используют освещение.

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-компонент

Параметр:

ambient

определяет влияние окружающего освещения.

Пример:

material: {
  ambient: 0.2
}

Поверхность становится более контрастной.

Увеличение значения:

material: {
  ambient: 1.0
}

делает объект более равномерно освещённым.


Diffuse-компонент

Параметр:

diffuse

определяет рассеянное отражение света.

Пример:

material: {
  diffuse: 0.8
}

Высокое значение подчёркивает объём объектов.

Низкое значение:

material: {
  diffuse: 0.1
}

делает влияние точечного света менее заметным.


Specular-компонент

Зеркальная составляющая отвечает за блики.

Настройка:

material: {
  specularColor: [255, 255, 255]
}

Белые блики характерны для:

  • металла;
  • стекла;
  • полированного пластика.

Цвет блика можно изменить:

material: {
  specularColor: [255, 200, 150]
}

Shininess

Параметр определяет концентрацию блика.

Низкое значение:

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;
  • слишком сильный Ambient Light;
  • источник света расположен прямо над объектом.

Решение:

material: {
  diffuse: 0.8
}

Отсутствуют блики

Причины:

  • маленькое значение shininess;
  • нулевой specularColor;
  • неподходящее положение камеры.

Проверка:

material: {
  shininess: 64,
  specularColor: [255, 255, 255]
}

Полный пример настройки Point Light

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.