Equirectangular-панорама как фон

Equirectangular-панорама представляет собой 2D-изображение, проецированное в виде сферы, которое охватывает полный 360° по горизонтали и 180° по вертикали. В Three.js такой подход часто используется для создания реалистичных фонов сцены, имитации окружающей среды и для реализации эффектов отражений.


Подготовка сцены

Для начала необходимо создать базовые элементы сцены: сцену, камеру и рендерер. Камера обычно используется типа PerspectiveCamera, поскольку она обеспечивает естественную перспективу для 3D-объектов.

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
    75, 
    window.innerWidth / window.innerHeight, 
    0.1, 
    1000
);
camera.position.set(0, 0, 0);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

Загрузка equirectangular-текстуры

Three.js предоставляет TextureLoader для загрузки изображений. Для корректного отображения панорамы важно использовать текстуры с соотношением сторон 2:1.

const loader = new THREE.TextureLoader();
loader.load('path/to/panorama.jpg', function(texture) {
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.background = texture;
});

Ключевой момент: Использование THREE.EquirectangularReflectionMapping позволяет текстуре корректно отображаться в качестве окружающей среды, обеспечивая правильное искажение при проекции на сферу.


Использование CubeTextureLoader (альтернатива)

Для некоторых случаев можно использовать кубическую текстуру, но equirectangular-панорама более гибкая и подходит для динамических сцен. При необходимости конвертации equirectangular в кубическую текстуру применяется PMREMGenerator:

const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();

loader.load('path/to/panorama.jpg', function(texture) {
    const envMap = pmremGenerator.fromEquirectangular(texture).texture;
    scene.background = envMap;
    scene.environment = envMap;
    texture.dispose();
    pmremGenerator.dispose();
});

Пояснение: scene.environment используется для глобального освещения объектов сцены, особенно металлизированных поверхностей (MeshStandardMaterial или MeshPhysicalMaterial). Это позволяет добиться реалистичных отражений и освещенности.


Создание сферы с панорамой

Иногда предпочтительнее проецировать панораму на сферу, чтобы получить полный контроль над визуализацией:

const geometry = new THREE.SphereGeometry(500, 60, 40);
geometry.scale(-1, 1, 1); // Инвертирование сферы для корректного отображения изнутри

const material = new THREE.MeshBasicMaterial({
    map: loader.load('path/to/panorama.jpg')
});

const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

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

  • Инвертирование сферы geometry.scale(-1, 1, 1) необходимо, чтобы текстура отображалась на внутренней поверхности.
  • MeshBasicMaterial подходит для фонов, так как не реагирует на освещение, что позволяет сохранять естественные цвета панорамы.

Анимация и управление камерой

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

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;
controls.enablePan = false;
controls.rotateSpeed = -0.25; // Инвертирование вращения для панорамы

function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
}

animate();

Совет: Отключение масштабирования и панорамирования предотвращает выход за пределы сферы и сохраняет ощущение погружения в окружение.


Оптимизация производительности

  • Использовать текстуры с разрешением, соответствующим экрану. Избыточное разрешение замедляет рендеринг.
  • Генерация PMREM оптимальна для материалов с отражениями, но тяжелая операция — можно предварительно сохранять конвертированную текстуру.
  • Минимизировать количество геометрии вокруг сцены, так как панорама обычно занимает весь фон.

Работа с динамическими панорамами

Для смены фона в реальном времени можно просто подменять текстуру:

loader.load('path/to/new_panorama.jpg', function(newTexture) {
    newTexture.mapping = THREE.EquirectangularReflectionMapping;
    scene.background = newTexture;
});

Это позволяет создавать интерактивные сцены с разными окружениями без пересоздания всей сцены.


Взаимодействие с материалами сцены

При использовании equirectangular-панорамы в scene.environment объекты с MeshStandardMaterial автоматически будут получать отражения и световые эффекты от текстуры:

const material = new THREE.MeshStandardMaterial({
    color: 0xffffff,
    metalness: 1,
    roughness: 0
});

const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), material);
scene.add(sphere);

Эффект: Металлизированные объекты будут отражать окружение панорамы, создавая фотореалистичное освещение и блики.


Поддержка HDR-панорам

Three.js поддерживает HDR-изображения в формате .hdr или .exr. Для загрузки таких текстур используется RGBELoader:

const rgbeLoader = new THREE.RGBELoader();
rgbeLoader.load('path/to/panorama.hdr', function(texture) {
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.background = texture;
    scene.environment = texture;
});

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


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