Динамические тени: ShadowGenerator

Babylon.js предоставляет мощные инструменты для работы с 3D-графикой в браузере, включая систему динамических теней. Одним из важнейших классов для управления тенями является ShadowGenerator, который позволяет создавать тени для объектов в сцене, обеспечивая их реалистичность и плавность. В этой статье подробно рассматривается использование ShadowGenerator для создания и настройки динамических теней в Babylon.js.

Что такое ShadowGenerator?

ShadowGenerator — это класс, предназначенный для генерации теней в 3D-сценах. Он принимает в расчет источники света и объекты, которые могут отбрасывать тени, а также рендерит эти тени на специальном объекте текстуры, называемом тенью карты (shadow map). Тени могут быть использованы для улучшения визуального восприятия сцены, добавляя глубину и контекст.

Основные компоненты системы теней

Система динамических теней в Babylon.js включает несколько важных элементов:

  • Light: Источник света, от которого будут отбрасываться тени. Наиболее часто используются точечные и направленные источники света.
  • ShadowGenerator: Объект, который отвечает за создание и настройку карты теней, а также за взаимодействие с источниками света и объектами сцены.
  • ShadowMap: Текстура, в которой хранятся сгенерированные тени. Она используется для наложения теней на объекты сцены при рендеринге.

Создание ShadowGenerator

Для создания генератора теней используется класс ShadowGenerator, которому передается источник света. Обычно это делается следующим образом:

// Создание источника света
const light = new BABYLON.DirectionalLight("dirLight", new BABYLON.Vector3(0, -1, 1), scene);

// Создание генератора теней для источника света
const shadowGenerator = new BABYLON.ShadowGenerator(1024, light);

Здесь создается направленный свет (DirectionalLight), и затем на основе этого источника создается объект ShadowGenerator. В конструкторе ShadowGenerator первым параметром указывается разрешение текстуры тени (например, 1024), а вторым — источник света.

Настройка объектов, которые будут отбрасывать тени

Чтобы объект начал отбрасывать тени, необходимо явно указать это через свойство receiveShadows на материале объекта или через соответствующие свойства геометрии. Например:

const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
sphere.position.y = 1;

// Включение отбрасывания теней
sphere.receiveShadows = true;

Для того чтобы объект отбрасывал тени, нужно настроить его материал:

const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);

// Включение отбрасывания теней
ground.receiveShadows = true;

Тени на источниках света

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

Типы теней

Babylon.js поддерживает несколько типов теней, которые могут быть использованы для создания различных визуальных эффектов:

  1. PCF (Percentage Closer Filtering) — стандартный метод размытия теней.
  2. PCFSoft — более мягкие тени, основанные на тех же принципах, но с более плавным переходом.
  3. Esm (Exponential Shadow Maps) — алгоритм, использующий экспоненциальное размытие теней, что дает более качественные результаты при меньших вычислительных затратах.

Тип теней настраивается с помощью свойства filteringQuality:

shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH;

Для выбора типа теней можно использовать свойство shadowGenerator.usePoissonSampling для включения случайного сэмплинга:

shadowGenerator.usePoissonSampling = true;
Пример использования фильтрации
shadowGenerator.usePoissonSampling = true;
shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_LOW;

Настройка параметров генератора теней

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

  • bias: Регулирует смещение теней, что может помочь избежать артефактов, таких как «шумы» или «зазоры» между объектами и их тенями.
shadowGenerator.bias = 0.0001;
  • darkness: Этот параметр отвечает за затемнение теней. Чем выше значение, тем темнее будут тени.
shadowGenerator.darkness = 0.5;
  • blurWidth: Ширина размытия для теней, если используется фильтрация.
shadowGenerator.blurWidth = 4;

Тени на различных источниках света

Babylon.js позволяет генерировать тени не только для направленных источников света, но и для точечных источников и источников, создающих тени с эффектом глобального освещения.

Направленный свет

Для направленного света, как правило, используется DirectionalLight. Этот свет имитирует свет от бесконечно удаленной точки и подходит для создания теней от солнечного света.

Точечный свет

Точечные источники света могут создавать более мягкие тени с радиусом. Для таких источников света генерация теней работает немного по-другому, и потребуется настраивать параметры с учетом радиуса и интенсивности света.

const pointLight = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(0, 5, 0), scene);
const pointShadowGenerator = new BABYLON.ShadowGenerator(1024, pointLight);
Сферы и другие формы света

Свет в Babylon.js может быть представлен не только направленными и точечными источниками. Например, для создания теней с размытиями, для объемного света, можно использовать дополнительные световые объекты.

Отображение теней

Тени обычно не видны напрямую, а накладываются на сцены как текстуры. Они могут быть применены на объекты с помощью материала или через шейдеры.

Для отображения карты теней на объекте используется материал, который поддерживает тени. Например, материал StandardMaterial автоматически учитывает тени, если они включены в сцену.

const material = new BABYLON.StandardMaterial("mat", scene);
material.shadowLevel = 0.5;
sphere.material = material;

Проблемы и оптимизация

Генерация динамических теней может быть ресурсоемким процессом, особенно в больших сценах с множеством объектов и источников света. Чтобы оптимизировать производительность, можно использовать следующие методы:

  1. Использование меньшего разрешения теней: Чем ниже разрешение текстуры тени, тем быстрее будет работать генерация.
  2. Использование поочередных обновлений карт теней: Для объектов, находящихся далеко от камеры или скрытых за другими объектами, можно не генерировать тени.

Заключение

ShadowGenerator в Babylon.js предоставляет мощные инструменты для работы с динамическими тенями в 3D-сценах. С помощью этого класса можно эффективно генерировать и настраивать тени, улучшая реалистичность сцены и улучшая восприятие глубины. Важно учитывать характеристики света, объекта и самой текстуры тени, чтобы достичь оптимального качества и производительности.