CubeCamera: динамические отражения

В Three.js объект CubeCamera используется для создания динамических отражений, генерируя кубическую карту окружающей сцены, которая затем может применяться к материалам с отражающими свойствами. Это особенно полезно для создания зеркальных поверхностей, металлов и водной глади с реалистичными отражениями.


Принцип работы CubeCamera

CubeCamera представляет собой виртуальную камеру, которая рендерит сцену с точки зрения шести направлений: +X, -X, +Y, -Y, +Z, -Z. Результатом является текстура типа WebGLCubeRenderTarget, которая содержит все шесть изображений и может использоваться как environment map для материалов.

Порядок действий следующий:

  1. Размещение CubeCamera в точке, откуда должен происходить обзор отражений.
  2. Вызов метода .update(renderer, scene) для рендера сцены во все шесть направлений.
  3. Применение полученной кубической текстуры к материалу объекта.

Создание и использование CubeCamera

// Создание кубической камеры
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256, {
    format: THREE.RGBAFormat,
    generateMipmaps: true,
    minFilter: THREE.LinearMipmapLinearFilter,
    encoding: THREE.sRGBEncoding
});

const cubeCamera = new THREE.CubeCamera(0.1, 1000, cubeRenderTarget);
scene.add(cubeCamera);
  • 256 — размер текстуры (ширина и высота каждой грани куба).
  • format — формат пикселей (обычно THREE.RGBAFormat).
  • generateMipmaps — создание мипмапов для улучшения качества при масштабировании.
  • encoding — цветовое пространство (sRGBEncoding обеспечивает корректные цвета для PBR-материалов).

Для применения отражений к материалу используется material.envMap:

const reflectiveMaterial = new THREE.MeshStandardMaterial({
    metalness: 1,
    roughness: 0,
    envMap: cubeRenderTarget.texture
});

const reflectiveSphere = new THREE.Mesh(
    new THREE.SphereGeometry(1, 32, 32),
    reflectiveMaterial
);
scene.add(reflectiveSphere);

Динамическое обновление отражений

Чтобы отражения реагировали на изменения сцены, необходимо обновлять CubeCamera каждый кадр или в моменты изменения сцены:

function animate() {
    requestAnimationFrame(animate);

    // Скрываем объект, чтобы он не появился в собственном отражении
    reflectiveSphere.visible = false;

    // Обновление кубической карты
    cubeCamera.update(renderer, scene);

    // Отображаем объект снова
    reflectiveSphere.visible = true;

    renderer.render(scene, mainCamera);
}
animate();

Ключевой момент: объект, для которого создаются отражения, должен быть временно скрыт во время рендеринга CubeCamera, чтобы избежать самоотражения.


Настройка качества отражений

  • Размер текстуры (WebGLCubeRenderTarget) — влияет на четкость отражений. Для динамичных объектов обычно достаточно 256–512, для статичных сцен можно использовать 1024 и выше.
  • Mipmaps и фильтрыLinearMipmapLinearFilter улучшает качество при отдалении.
  • near и far камеры — определяют диапазон, в котором объекты будут видны в отражении. Оптимальные значения уменьшают искажения и улучшают производительность.

Использование CubeCamera для реалистичной воды

CubeCamera часто применяется для имитации зеркальной поверхности воды. В сочетании с шейдерами и нормалями воды можно получить эффект отражений окружающей сцены, движущейся воды и динамичных бликов.

Пример использования в сочетании с MeshStandardMaterial для плоской поверхности воды:

const waterMaterial = new THREE.MeshStandardMaterial({
    color: 0x001e0f,
    metalness: 0.6,
    roughness: 0.1,
    envMap: cubeRenderTarget.texture
});

const waterPlane = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10),
    waterMaterial
);
waterPlane.rotation.x = - Math.PI / 2;
scene.add(waterPlane);

Ограничения и оптимизация

  1. Производительность: рендеринг сцены шесть раз на каждый кадр может быть тяжелым. Для оптимизации:

    • Обновлять CubeCamera только при изменении позиции объектов.
    • Использовать меньший размер текстуры для динамических объектов и более крупный для статических.
  2. Самоотражение: необходимо скрывать объект при рендере CubeCamera.

  3. Поддержка PBR: CubeCamera отлично работает с PBR-материалами (MeshStandardMaterial, MeshPhysicalMaterial), позволяя использовать динамическое освещение.


Практическая схема применения CubeCamera

  1. Создать CubeCamera с подходящими параметрами.
  2. Добавить камеру в сцену в точку отражения.
  3. Скрывать объект на время рендеринга кубической карты.
  4. Вызвать .update(renderer, scene) для генерации кубической карты.
  5. Назначить полученную текстуру envMap объекту.
  6. В случае динамических сцен повторять шаги 3–5 при изменении положения объектов или освещения.

Заключение по функциональности CubeCamera

CubeCamera предоставляет мощный инструмент для реализации реалистичных отражений и динамических environment maps. Правильная организация рендеринга, использование оптимальных размеров текстуры и фильтров позволяет сочетать визуальное качество с производительностью. Эта техника является основой для создания металлических поверхностей, зеркал и водных эффектов в 3D-сценах на базе Three.js.