PMREMGenerator: предвычисление освещения из HDR

PMREMGenerator — специализированный инструмент библиотеки Three.js, предназначенный для эффективного использования HDR-текстур (High Dynamic Range) в PBR-сценах (Physically Based Rendering). Основная задача — создание предвычисленных карт окружения, которые позволяют реалистично освещать объекты без затрат на онлайн-расчёт глобального освещения.


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

HDR-текстуры содержат широкие диапазоны яркости, которые сложно напрямую использовать для освещения сцены. PMREMGenerator преобразует HDR-карту в Prefiltered Mipmapped Radiance Environment Map (PMREM) — серию текстур с разной степенью размытия (мип-уровней), каждая из которых соответствует разной шероховатости поверхности.

Ключевые шаги процесса:

  1. Загрузка HDR-текстуры Обычно используется RGBELoader или EXRLoader. Результатом является DataTexture с высокой динамикой яркости.

  2. Создание PMREM

    const pmremGenerator = new THREE.PMREMGenerator(renderer);
    pmremGenerator.compileEquirectangularShader();
    
    const envMap = pmremGenerator.fromEquirectangular(hdrTexture).texture;

    Здесь fromEquirectangular принимает HDR в виде equirectangular-карты и возвращает предвычисленное окружение, готовое для PBR-материалов.

  3. Использование с PBR-материалами

    const material = new THREE.MeshStandardMaterial({
        envMap: envMap,
        metalness: 1.0,
        roughness: 0.3
    });

    В результате объекты реагируют на свет максимально реалистично: блестящие поверхности отражают свет мягко и корректно, а шероховатые — более рассеянно.


Основные методы и параметры

  • fromEquirectangular(texture: Texture) — преобразует HDR-карту в PMREM для использования в PBR-материалах.
  • fromCubemap(cubeRenderTarget: WebGLCubeRenderTarget) — аналогичный метод, но для кубических текстур.
  • compileEquirectangularShader() / compileCubemapShader() — предварительная компиляция шейдеров для ускорения генерации.
  • dispose() — освобождает ресурсы GPU после завершения работы.

Особенности и рекомендации

  1. Оптимизация производительности PMREM предвычисляется один раз при загрузке HDR. После этого можно многократно применять envMap к различным материалам без перерасчёта.

  2. Поддержка miplevels PMREM автоматически генерирует мип-уровни для разных значений шероховатости, что обеспечивает корректное размытие отражений в зависимости от материала.

  3. Совместимость с Linear / sRGB HDR-текстуры обычно работают в линейном цвете (THREE.LinearEncoding). После преобразования PMREM используется THREE.RGBEEncoding или THREE.LinearEncoding, в зависимости от настроек рендерера.

  4. Очистка ресурсов Генератор создаёт временные рендер-таргеты, которые необходимо удалять после использования:

    pmremGenerator.dispose();
    hdrTexture.dispose();

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

Equirectangular HDR для сцены с металлом:

const loader = new THREE.RGBELoader();
loader.load('textures/env.hdr', function(hdrTexture) {
    hdrTexture.mapping = THREE.EquirectangularReflectionMapping;

    const pmremGenerator = new THREE.PMREMGenerator(renderer);
    const envMap = pmremGenerator.fromEquirectangular(hdrTexture).texture;

    const sphere = new THREE.Mesh(
        new THREE.SphereGeometry(1, 64, 64),
        new THREE.MeshStandardMaterial({
            envMap: envMap,
            metalness: 1.0,
            roughness: 0.2
        })
    );

    scene.add(sphere);
    pmremGenerator.dispose();
});

Cubemap HDR для PBR-материалов:

const cubeLoader = new THREE.CubeTextureLoader();
const hdrCube = cubeLoader.load([
    'px.hdr', 'nx.hdr',
    'py.hdr', 'ny.hdr',
    'pz.hdr', 'nz.hdr'
]);

const pmremGenerator = new THREE.PMREMGenerator(renderer);
const envMap = pmremGenerator.fromCubemap(hdrCube).texture;

mesh.material.envMap = envMap;
pmremGenerator.dispose();

Преимущества использования PMREM

  • Реалистичное освещение без затрат на динамическое глобальное освещение.
  • Высокая производительность, так как расчёт происходит один раз при загрузке.
  • Поддержка любых HDR-источников, как equirectangular, так и кубических.
  • Совместимость с PBR-материалами, включая MeshStandardMaterial и MeshPhysicalMaterial.

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