Формат STL (Stereolithography) широко используется в трёхмерной графике, CAD-системах и особенно в сфере 3D-печати. Файлы STL описывают геометрию модели в виде набора треугольников, определяющих поверхность объекта. Внутри файла содержится информация о координатах вершин и нормалях, но отсутствуют сведения о цветах, текстурах, материалах и иерархии сцены.
В экосистеме Three.js для загрузки таких моделей используется класс STLLoader, входящий в набор дополнительных модулей библиотеки. Загрузчик предназначен для чтения STL-файлов и преобразования содержащихся в них данных в объект BufferGeometry, который затем может быть отображён в сцене.
Основные возможности STLLoader:
STLLoader применяется для визуализации моделей из инженерных систем, демонстрации результатов 3D-печати, научной визуализации и просмотра CAD-геометрии в браузере.
Загрузчик располагается в каталоге examples/jsm/loaders
репозитория Three.js и подключается как ES-модуль.
import * as THREE from 'three';
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
После импорта создаётся экземпляр загрузчика.
const loader = new STLLoader();
Загрузчик работает поверх стандартной системы FileLoader, поэтому поддерживает асинхронную загрузку и обратные вызовы.
Загрузка осуществляется методом load().
loader.load(
'models/model.stl',
function (geometry) {
const material = new THREE.MeshStandardMaterial({
color: 0x999999,
metalness: 0.1,
roughness: 0.7
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
);
Метод load() принимает несколько параметров:
load(url, onLoad, onProgress, onError)
url — путь к STL-файлу. onLoad — функция, вызываемая после загрузки и парсинга. onProgress — обработчик прогресса загрузки. onError — обработчик ошибок.
После завершения загрузки передаётся объект BufferGeometry, содержащий данные модели.
Файл STL представляет собой набор треугольников. Каждый треугольник описывается:
Пример структуры ASCII STL:
facet normal 0 0 1
outer loop
vertex 0 0 0
vertex 1 0 0
vertex 0 1 0
endloop
endfacet
Binary STL имеет более компактный формат:
Каждый треугольник занимает 50 байт:
STLLoader автоматически определяет тип файла и выбирает соответствующий алгоритм парсинга.
Результатом работы STLLoader является объект THREE.BufferGeometry.
Он содержит следующие атрибуты:
| Атрибут | Назначение |
|---|---|
| position | координаты вершин |
| normal | нормали поверхностей |
В отличие от многих других форматов, STL:
Поэтому после загрузки необходимо самостоятельно назначать материал.
Для визуализации STL-моделей чаще всего используются следующие материалы:
Подходит для физически корректного освещения.
const material = new THREE.MeshStandardMaterial({
color: 0x777777,
roughness: 0.6,
metalness: 0.1
});
Используется при простых источниках света.
const material = new THREE.MeshPhongMaterial({
color: 0xaaaaaa,
shininess: 100
});
Отображает нормали поверхности и применяется для отладки геометрии.
const material = new THREE.MeshNormalMaterial();
Многие STL-файлы создаются в единицах миллиметров. В сцене Three.js масштаб может отличаться, поэтому часто применяется масштабирование.
mesh.scale.set(0.01, 0.01, 0.01);
Также может потребоваться центрирование модели.
geometry.center();
Система координат STL может отличаться от системы Three.js. Часто требуется поворот модели.
mesh.rotation.x = -Math.PI / 2;
Это особенно характерно для моделей, экспортированных из CAD-программ.
STLLoader поддерживает работу с LoadingManager, который позволяет отслеживать загрузку нескольких ресурсов.
const manager = new THREE.LoadingManager();
manager.onSt art = function () {
console.log('Загрузка началась');
};
manager.onL oad = function () {
console.log('Все ресурсы загружены');
};
const loader = new STLLoader(manager);
Такой подход применяется в сложных приложениях с большим количеством моделей.
В одной сцене может использоваться несколько STL-объектов.
const loader = new STLLoader();
loader.load('models/base.stl', function (geometry) {
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
loader.load('models/detail.stl', function (geometry) {
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 10, 0);
scene.add(mesh);
});
Каждая модель загружается независимо.
STLLoader может обрабатывать данные без загрузки файла напрямую.
Метод parse() принимает массив байтов.
const geometry = loader.parse(arrayBuffer);
Такой способ применяется при:
fetch;Пример:
fetch('model.stl')
.then(response => response.arrayBuffer())
.then(data => {
const geometry = loader.parse(data);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
STL-модели могут содержать огромное количество треугольников. Это влияет на производительность.
Основные методы оптимизации:
Перед использованием STL рекомендуется уменьшить количество полигонов в 3D-редакторе:
STLLoader уже возвращает BufferGeometry, что снижает нагрузку на память и GPU.
Если файл не содержит нормалей, можно пересчитать их.
geometry.computeVertexNormals();
Для анализа структуры модели иногда требуется отображение каркаса.
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
wireframe: true
});
Каркасная визуализация полезна для:
Для корректного отображения геометрии важна настройка освещения.
Пример базовой схемы:
const light1 = new THREE.DirectionalLight(0xffffff, 1);
light1.position.set(10, 10, 10);
scene.add(light1);
const light2 = new THREE.AmbientLight(0x404040);
scene.add(light2);
Направленный свет подчёркивает форму поверхности, а окружающий свет предотвращает слишком тёмные области.
При работе с очень крупными STL-файлами могут возникать проблемы:
Практические решения:
1. Разделение модели на части
Крупные модели можно экспортировать в виде нескольких STL-файлов.
2. Использование Web Workers
Парсинг STL можно выполнять в отдельном потоке.
3. Использование формата glTF
Для сложных сцен предпочтительнее применять glTF, так как он поддерживает:
STL лучше подходит для чистой геометрии.
Некоторые модели отображаются тёмными или невидимыми. Причина — неправильное направление нормалей.
Решение:
material.side = THREE.DoubleSide;
или пересчёт нормалей.
Если модель не видна, возможно она слишком большая или слишком маленькая.
Проверка:
console.log(geometry.boundingBox);
Многие STL-файлы имеют смещение относительно начала координат.
Решение:
geometry.center();
import * as THREE from 'three';
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 50, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 20, 10);
scene.add(light);
const loader = new STLLoader();
loader.load('model.stl', function (geometry) {
geometry.center();
const material = new THREE.MeshStandardMaterial({
color: 0x888888
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
Данный пример демонстрирует базовый цикл рендеринга, загрузку STL-файла и отображение модели в сцене Three.js.
STLLoader применяется в следующих областях:
Несмотря на простоту формата, STL остаётся одним из наиболее распространённых способов передачи трёхмерной геометрии между различными программами и платформами.