Тени: shadowMap и типы PCFShadowMap, VSMShadowMap

Three.js предоставляет мощный инструмент для работы с тенями, основанный на механизме shadowMap. Тени создают ощущение глубины и реалистичности сцены, но их корректная настройка требует понимания ключевых параметров и типов карт теней.


Включение теней

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

const light = new THREE.DirectionalLight(0xffffff, 1);
light.castShadow = true; // Источник света отбрасывает тени

const mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;    // Объект отбрасывает тень
mesh.receiveShadow = true; // Объект принимает тень

scene.add(light, mesh);
renderer.shadowMap.enabled = true; // Включение рендерера для работы с тенями

Ключевые моменты:

  • castShadow и receiveShadow нужно задавать для каждого объекта отдельно.
  • Тень создается только источниками света, поддерживающими тени (DirectionalLight, SpotLight, PointLight).
  • Рендерер должен иметь включенную опцию shadowMap.enabled.

Типы теневых карт

Three.js поддерживает несколько алгоритмов рендеринга теней, которые определяются свойством renderer.shadowMap.type. Основные типы:

THREE.PCFShadowMap

PCF (Percentage-Closer Filtering) — базовый тип сглаживания теней. Обеспечивает мягкие края тени за счет усреднения нескольких выборок вокруг пикселя.

Особенности:

  • Хорошо подходит для большинства сцен.
  • Производительность средняя.
  • Эффект «мягкости» зависит от разрешения карты теней (shadow.mapSize) и настроек фильтрации.

Пример использования:

renderer.shadowMap.type = THREE.PCFShadowMap;

THREE.PCFSoftShadowMap

Улучшенная версия PCF с более плавными краями. Требует чуть больше вычислений, но визуально тени выглядят более мягкими.

renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  • Эффективно для сцен с большим количеством объектов.
  • Меньше артефактов на границах тени, особенно на наклонных поверхностях.

THREE.VSMShadowMap

VSM (Variance Shadow Map) — продвинутый метод рендеринга теней, использующий статистику для сглаживания. Позволяет создавать мягкие тени и уменьшает эффект «ступенчатости».

Особенности:

  • Обеспечивает корректное размытие теней.
  • Может приводить к артефактам при слишком высокой контрастности света.
  • Требует правильной настройки light.shadow.bias и light.shadow.normalBias.

Пример настройки:

renderer.shadowMap.type = THREE.VSMShadowMap;

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
directionalLight.shadow.bias = -0.0001;
directionalLight.shadow.normalBias = 0.05;
scene.add(directionalLight);

Параметры карты теней

Для всех типов карт важно настраивать несколько ключевых свойств:

  1. Размер карты теней (shadow.mapSize)

    Определяет разрешение текстуры, в которой хранится тень. Большие значения дают более детализированные тени, но увеличивают нагрузку на GPU.

    light.shadow.mapSize.width = 2048;
    light.shadow.mapSize.height = 2048;
  2. Bias (shadow.bias)

    Используется для предотвращения артефактов «пронизывания» (shadow acne), когда тень неправильно накладывается на объект.

    light.shadow.bias = -0.0005;
  3. Normal Bias (shadow.normalBias)

    Позволяет смещать тень по нормали поверхности, улучшая корректность теней на наклонных объектах. Особенно важно при использовании VSM.

    light.shadow.normalBias = 0.05;
  4. Камера теней (shadow.camera)

    Для источников света с направлением (DirectionalLight) можно настроить камеру, которая определяет область рендеринга тени.

    light.shadow.camera.left = -10;
    light.shadow.camera.right = 10;
    light.shadow.camera.top = 10;
    light.shadow.camera.bottom = -10;
    light.shadow.camera.near = 0.5;
    light.shadow.camera.far = 50;

    Это позволяет оптимизировать качество тени, уменьшая лишние области вне сцены.


Оптимизация теней

  • Сократить разрешение карты для объектов, находящихся далеко от камеры.
  • Использовать PCFSoftShadowMap для сцен с умеренной детализацией, а VSMShadowMap — для сцен с мягким освещением и высоким качеством теней.
  • Настройка bias и normalBias критична для удаления артефактов.
  • Ограничить размеры камеры теней (shadow.camera) для направленных источников, чтобы увеличить резкость и снизить нагрузку.

Итоговые рекомендации по выбору типа теней

Тип теней Качество краев Производительность Особенности
PCFShadowMap Среднее Средняя Хорошо для большинства сцен
PCFSoftShadowMap Мягкое Средне-низкая Плавные края, меньше артефактов
VSMShadowMap Высокое Средне-высокая Подходит для мягких и размытых теней, требует корректного bias

Правильная комбинация типа карты теней, размеров mapSize и смещений bias/normalBias позволяет получить реалистичные, чистые и оптимизированные тени, подходящие под любую сцену в Three.js.