Настройка камеры тени: shadowCamera

В Three.js для генерации теней используется система рендеринга теней, в которой ключевую роль играет камера света, называемая shadow.camera. Понимание и правильная настройка этой камеры критично для получения качественных и корректных теней в сцене.

Типы источников света и их камеры теней

В зависимости от типа источника света в Three.js, shadow.camera может иметь разные формы:

  • DirectionalLight – использует ортографическую камеру (THREE.OrthographicCamera). Тени генерируются как параллельные лучи, что идеально для имитации солнечного света.
  • SpotLight – использует перспективную камеру (THREE.PerspectiveCamera). Тени направленные, с перспективным сжатием, подходящие для точечных источников света.
  • PointLight – использует кубическую камеру (THREE.CubeCamera). Позволяет создавать тени во всех направлениях вокруг точки.

Основные свойства shadow.camera

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

  1. near и far – определяют минимальную и максимальную дистанцию от источника света, на которой будут отбрасываться тени. Установка слишком большого диапазона снижает точность теней из-за дискретизации карты теней.

    light.shadow.camera.near = 1;
    light.shadow.camera.far = 100;
  2. left, right, top, bottom – применяются для ортографических камер (DirectionalLight). Эти параметры задают границы камеры, определяя область сцены, где будут видны тени. Если тени обрезаются, необходимо увеличить эти значения:

    light.shadow.camera.left = -10;
    light.shadow.camera.right = 10;
    light.shadow.camera.top = 10;
    light.shadow.camera.bottom = -10;
  3. fov – угол обзора для перспективных камер (SpotLight). От него зависит, насколько широкая область освещается источником света и, соответственно, тени охватывают сцену:

    light.shadow.camera.fov = 45;
  4. radius – управляет размытие краев тени (soft shadows) в некоторых типах источников света, улучшая реализм теней.

Карта теней (shadow map) и её разрешение

shadow.mapSize определяет разрешение текстуры, на которую проецируются тени. Низкое разрешение приводит к зернистым или пиксельным теням. Для повышения качества используют значения от 1024 до 4096 пикселей:

light.shadow.mapSize.width = 2048;
light.shadow.mapSize.height = 2048;

Визуализация камеры теней

Для отладки удобно отображать камеру теней в сцене с помощью CameraHelper:

const helper = new THREE.CameraHelper(light.shadow.camera);
scene.add(helper);

Это позволяет увидеть границы зоны, где рассчитываются тени, и скорректировать left, right, top, bottom, near и far без проб и ошибок.

Баланс качества и производительности

Качество теней зависит от нескольких факторов:

  • Размер карты теней (mapSize). Чем выше разрешение, тем точнее, но выше нагрузка на GPU.
  • Размер зоны камеры (shadow.camera). Слишком большая зона уменьшает точность, слишком маленькая обрезает тени.
  • Расстояние near и far. Оптимальный диапазон минимизирует артефакты, такие как «плавающие» или «ломаные» тени.

Практические советы

  • Для солнечного света (DirectionalLight) рекомендуется использовать ортографическую камеру, охватывающую только ту область сцены, где будут объекты отбрасывать тень.
  • Для направленных SpotLight часто достаточно небольшого угла обзора (fov), чтобы улучшить детализацию тени.
  • Если тени кажутся резкими или нереалистичными, увеличьте radius и проверьте фильтрацию карты теней через THREE.PCFSoftShadowMap.
  • Для динамических сцен с большим количеством объектов важно избегать слишком высоких mapSize, чтобы не перегружать рендеринг.

Итоговые ключевые моменты

  • shadow.camera определяет видимую область для теней.
  • Настройка near, far, left, right, top, bottom и fov критична для точности теней.
  • Баланс между качеством теней и производительностью достигается через корректный выбор размера карты теней и параметров камеры.
  • Использование CameraHelper облегчает отладку и настройку.

Правильная конфигурация shadow.camera позволяет создавать реалистичные и управляемые тени, существенно повышая визуальное качество сцены в Three.js.