OBJLoader и MTLLoader

В веб-графике часто используется внешняя 3D-геометрия, созданная в специализированных редакторах: Blender, Maya, 3ds Max, Cinema4D. Для интеграции таких моделей в сцену Three.js применяются загрузчики форматов. Одним из самых распространённых является формат OBJ, который сопровождается файлами материалов MTL.

Библиотека Three.js предоставляет специализированные загрузчики:

  • OBJLoader — загружает геометрию из файлов .obj
  • MTLLoader — загружает материалы из файлов .mtl

Совместное использование этих загрузчиков позволяет корректно импортировать не только геометрию, но и материалы, текстуры и базовые свойства поверхности.


Формат OBJ

Формат OBJ — текстовый формат описания трёхмерной геометрии, разработанный компанией Wavefront Technologies. Его главные особенности:

  • хранение вершин
  • хранение нормалей
  • хранение текстурных координат
  • описание граней
  • ссылки на файлы материалов

Пример фрагмента OBJ-файла:

v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v -1.000000 -1.000000 -1.000000

vt 0.875000 0.500000
vt 0.625000 0.750000

vn 0.0000 0.0000 -1.0000

f 1/1/1 2/2/1 3/3/1

Обозначения:

Префикс Назначение
v координаты вершины
vt текстурные координаты
vn нормали
f грани

OBJ-файл может содержать ссылку на файл материалов:

mtllib model.mtl

Формат MTL

Файл MTL содержит описание материалов, применяемых к геометрии OBJ.

Типичный пример:

newmtl Material
Ka 1.000 1.000 1.000
Kd 0.640 0.640 0.640
Ks 0.500 0.500 0.500
map_Kd texture.jpg

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

Параметр Назначение
newmtl имя материала
Ka цвет окружающего освещения
Kd диффузный цвет
Ks зеркальный цвет
map_Kd текстура

MTLLoader преобразует эти параметры в соответствующие материалы Three.js.


Подключение загрузчиков

OBJLoader и MTLLoader не входят в базовый пакет Three.js и находятся в каталоге examples.

Импорт через ES-модули:

import * as THREE from 'three';

import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader.js';

Базовая загрузка OBJ-модели

Минимальный пример загрузки модели без материалов:

const loader = new OBJLoader();

loader.load(
    'models/model.obj',
    function (object) {

        scene.add(object);

    },
    function (xhr) {

        console.log((xhr.loaded / xhr.total * 100) + '% loaded');

    },
    function (error) {

        console.error('Ошибка загрузки', error);

    }
);

Метод load() принимает четыре параметра:

  1. путь к файлу
  2. callback успешной загрузки
  3. callback прогресса
  4. callback ошибки

После загрузки возвращается объект типа THREE.Group, содержащий геометрию модели.


Структура загруженной модели

OBJLoader преобразует модель в иерархию объектов Three.js.

Типичная структура:

Group
 ├ Mesh
 ├ Mesh
 └ Mesh

Каждый элемент:

  • Mesh
  • BufferGeometry
  • Material

Доступ к геометрии осуществляется через обход сцены:

object.traverse(function(child) {

    if (child.isMesh) {

        child.material.wireframe = true;

    }

});

Метод traverse() позволяет изменить свойства всех объектов внутри модели.


Использование MTLLoader

Для загрузки материалов сначала загружается файл .mtl, затем используется OBJLoader.

Этапы загрузки

  1. загрузка материалов
  2. подготовка материалов
  3. подключение материалов к OBJLoader
  4. загрузка модели

Пример полной загрузки OBJ + MTL

const mtlLoader = new MTLLoader();

mtlLoader.load('models/model.mtl', function(materials) {

    materials.preload();

    const objLoader = new OBJLoader();
    objLoader.setMaterials(materials);

    objLoader.load('models/model.obj', function(object) {

        scene.add(object);

    });

});

Метод setMaterials() сообщает OBJLoader, какие материалы использовать.

Метод preload() подготавливает материалы для использования.


Работа с текстурами

Если файл MTL содержит строки вида:

map_Kd texture.jpg

MTLLoader автоматически загружает текстуру.

Однако важно правильно указать путь:

mtlLoader.setPath('models/');
objLoader.setPath('models/');

Пример:

const mtlLoader = new MTLLoader();

mtlLoader.setPath('models/');

mtlLoader.load('model.mtl', function(materials) {

    materials.preload();

    const objLoader = new OBJLoader();
    objLoader.setMaterials(materials);
    objLoader.setPath('models/');

    objLoader.load('model.obj', function(object) {

        scene.add(object);

    });

});

Масштабирование модели

Модели из 3D-редакторов могут иметь очень большие или маленькие размеры.

Масштаб регулируется через свойство scale.

object.scale.set(0.1, 0.1, 0.1);

Или:

object.scale.multiplyScalar(0.5);

Позиционирование модели

После загрузки модель часто располагается в центре координат.

Перемещение:

object.position.set(0, 2, 0);

Поворот:

object.rotation.y = Math.PI / 2;

Работа с освещением

OBJ-модели используют стандартные материалы Three.js, поэтому корректное отображение зависит от освещения.

Типичный набор источников:

const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5,10,5);
scene.add(directionalLight);

Без источников света модель может выглядеть полностью чёрной.


Оптимизация моделей

OBJ-модели могут содержать большое количество полигонов.

Возможные проблемы:

  • низкая производительность
  • высокий объём загрузки
  • долгий парсинг

Основные методы оптимизации:

Уменьшение полигонов

Использование Decimate Modifier в Blender.

Сжатие текстур

Рекомендуемые форматы:

  • JPEG
  • WebP
  • KTX2

Использование более современных форматов

OBJ считается устаревшим форматом. Более эффективные альтернативы:

  • glTF
  • GLB

Однако OBJ остаётся популярным благодаря простоте и совместимости.


Асинхронная загрузка

Современные проекты часто используют Promise.

Пример:

function loadOBJ(path) {

    return new Promise((resolve, reject) => {

        const loader = new OBJLoader();

        loader.load(path, resolve, undefined, reject);

    });

}

Использование:

const model = await loadOBJ('model.obj');

scene.add(model);

Использование LoadingManager

LoadingManager позволяет отслеживать загрузку нескольких ресурсов.

Пример:

const manager = new THREE.LoadingManager();

manager.onSt art = function(url) {
    console.log('Начало загрузки', url);
};

manager.onL oad = function() {
    console.log('Все ресурсы загружены');
};

manager.onProgr ess = function(url, loaded, total) {
    console.log(loaded, total);
};

manager.onEr ror = function(url) {
    console.log('Ошибка загрузки', url);
};

Передача менеджера загрузчику:

const objLoader = new OBJLoader(manager);

Распространённые проблемы

Модель не отображается

Причины:

  • отсутствует освещение
  • неправильный масштаб
  • камера направлена в другую сторону
  • модель вне области видимости

Текстуры не загружаются

Причины:

  • неверный путь
  • неправильные ссылки внутри MTL
  • блокировка CORS

Чёрная модель

Причины:

  • отсутствуют нормали
  • нет освещения
  • материал не поддерживается

Альтернативные методы загрузки

Вместо MTLLoader можно назначить собственные материалы.

object.traverse(function(child) {

    if (child.isMesh) {

        child.material = new THREE.MeshStandardMaterial({
            color: 0x888888
        });

    }

});

Это позволяет игнорировать материалы из MTL и использовать собственную систему освещения.


Практическое применение

OBJLoader и MTLLoader широко используются для:

  • загрузки архитектурных моделей
  • интеграции моделей из Blender
  • демонстрации товаров
  • 3D-визуализации
  • прототипирования сцен
  • обучающих приложений WebGL

Несмотря на появление более современных форматов, поддержка OBJ остаётся важной частью экосистемы Three.js благодаря огромному количеству существующих моделей и простоте структуры формата.