В веб-графике часто используется внешняя 3D-геометрия, созданная в специализированных редакторах: Blender, Maya, 3ds Max, Cinema4D. Для интеграции таких моделей в сцену Three.js применяются загрузчики форматов. Одним из самых распространённых является формат OBJ, который сопровождается файлами материалов MTL.
Библиотека Three.js предоставляет специализированные загрузчики:
.obj.mtlСовместное использование этих загрузчиков позволяет корректно импортировать не только геометрию, но и материалы, текстуры и базовые свойства поверхности.
Формат 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 содержит описание материалов, применяемых к геометрии 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';
Минимальный пример загрузки модели без материалов:
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() принимает четыре параметра:
После загрузки возвращается объект типа THREE.Group, содержащий геометрию модели.
OBJLoader преобразует модель в иерархию объектов Three.js.
Типичная структура:
Group
├ Mesh
├ Mesh
└ Mesh
Каждый элемент:
Доступ к геометрии осуществляется через обход сцены:
object.traverse(function(child) {
if (child.isMesh) {
child.material.wireframe = true;
}
});
Метод traverse() позволяет изменить свойства всех объектов внутри модели.
Для загрузки материалов сначала загружается файл .mtl,
затем используется OBJLoader.
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.
Рекомендуемые форматы:
OBJ считается устаревшим форматом. Более эффективные альтернативы:
Однако 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 позволяет отслеживать загрузку нескольких ресурсов.
Пример:
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);
Причины:
Причины:
Причины:
Вместо MTLLoader можно назначить собственные материалы.
object.traverse(function(child) {
if (child.isMesh) {
child.material = new THREE.MeshStandardMaterial({
color: 0x888888
});
}
});
Это позволяет игнорировать материалы из MTL и использовать собственную систему освещения.
OBJLoader и MTLLoader широко используются для:
Несмотря на появление более современных форматов, поддержка OBJ остаётся важной частью экосистемы Three.js благодаря огромному количеству существующих моделей и простоте структуры формата.