CubeMap как скайбокс

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

В Three.js CubeMap создаётся с помощью объекта THREE.CubeTexture. Каждое изображение соответствует одной из сторон куба: положительной и отрицательной оси X, Y, Z.

const loader = new THREE.CubeTextureLoader();
const textureCube = loader.load([
    'px.jpg', // +X
    'nx.jpg', // -X
    'py.jpg', // +Y
    'ny.jpg', // -Y
    'pz.jpg', // +Z
    'nz.jpg'  // -Z
]);
scene.background = textureCube;

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

  • Порядок изображений критически важен и должен строго соответствовать осевому обозначению.
  • CubeMap можно использовать не только как фон сцены, но и для отражений объектов через material.envMap.

Создание скайбокса через CubeMap

Скайбокс — это визуальный приём, когда на внутренние грани большого куба проецируются изображения, создавая иллюзию окружающего мира. В Three.js существует два основных подхода:

  1. Через сцену и background: Используется scene.background = textureCube. В этом случае CubeMap автоматически растягивается на фон сцены, экономя ресурсы, так как не требуется отдельная геометрия.

  2. Через геометрию куба: Создаётся большой куб с материалом THREE.ShaderMaterial или THREE.MeshBasicMaterial с параметром side: THREE.BackSide. Этот метод позволяет дополнительно применять эффекты на скайбокс, например анимацию или смешивание текстур.

const geometry = new THREE.BoxGeometry(1000, 1000, 1000);
const material = new THREE.MeshBasicMaterial({
    envMap: textureCube,
    side: THREE.BackSide
});
const skybox = new THREE.Mesh(geometry, material);
scene.add(skybox);

Особенности метода с геометрией:

  • Куб создаётся с внутренней стороны (BackSide), чтобы текстура была видна изнутри.
  • Размер куба должен быть значительно больше любой сцены, чтобы камеры не пересекали его грани.
  • Можно комбинировать с динамическими CubeMap для анимации неба.

Использование CubeMap для отражений

CubeMap можно применять как источник для отражений на материалах объектов. В Three.js это делается через material.envMap. Например:

const reflectiveMaterial = new THREE.MeshStandardMaterial({
    color: 0xffffff,
    metalness: 1,
    roughness: 0,
    envMap: textureCube
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 32, 32), reflectiveMaterial);
scene.add(sphere);

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

  • metalness и roughness управляют интенсивностью и чёткостью отражения.
  • Для реалистичных отражений CubeMap должен соответствовать сцене по освещению и цветовой гамме.
  • Можно использовать PMREMGenerator для предварительной фильтрации текстуры, чтобы добиться корректных блестящих материалов.
const pmremGenerator = new THREE.PMREMGenerator(renderer);
const envMap = pmremGenerator.fromCubemap(textureCube).texture;
reflectiveMaterial.envMap = envMap;

Динамические и анимированные скайбоксы

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

  • Используется CubeCamera, которая снимает сцену с шести направлений, создавая обновляемую CubeMap.
  • Эта CubeMap затем применяется как envMap или фон.
const cubeCamera = new THREE.CubeCamera(1, 1000, 256);
scene.add(cubeCamera);
cubeCamera.update(renderer, scene);
scene.background = cubeCamera.renderTarget.texture;

Преимущества динамического CubeMap:

  • Позволяет создавать реалистичные отражения движущихся объектов.
  • Обеспечивает эффект глобального освещения через отражения.

Оптимизация и рекомендации

  1. Формат изображений: Использовать квадратные изображения одинакового размера для каждой грани. JPEG подойдёт для обычного фона, PNG — если нужна прозрачность.
  2. Размер куба: Скайбокс должен быть достаточно большим, чтобы камера не пересекала его грани, но не чрезмерно, чтобы не тратить память.
  3. Загрузка ассетов: Для ускорения отображения можно использовать THREE.LoadingManager и предварительно кэшировать текстуры.
  4. Фильтрация текстур: Использовать THREE.LinearFilter или THREE.LinearMipmapLinearFilter для плавного отображения без пикселизации.

Расширенные возможности

  • HDRI CubeMap: Использование HDR изображений позволяет создавать реалистичное освещение и отражения. В Three.js HDR изображения конвертируются через RGBELoader и PMREMGenerator.
  • Комбинированные CubeMap: Можно накладывать несколько CubeMap с разной интенсивностью для эффекта смещения света, тумана или постобработки.
  • Интерактивные скайбоксы: CubeMap может реагировать на действия пользователя, поворот камеры или анимацию объектов, создавая эффект присутствия в виртуальном пространстве.

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