Привет, хочу рассказать основу о том как быстро начать пилить продвинутые приложения с 3d моделями.
Для того чтобы лучше понимать контекст последующего материала ожидается что у тебя уже есть знания js, а также react. Также заранее оговорюсь что буду использовать упрощенное объяснения для наилучшего восприятия.
Содержание
Основные сущности threejs
Основные части модели
Загрузка модели
Загрузка анимации
Threejs и React
Основные сущности Three.js
Three.js построен вокруг нескольких ключевых сущностей. Разберём их с примерами кода.
Сцена — это контейнер (объект), в который ты помещаешь все объекты: геометрию, свет, модели, эффекты и т.п.
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222); // тёмно-серый фон
Камера — это глаз пользователя, который видит сцену. Объекты не отображаются, если они вне поля зрения камеры.
const camera = new THREE.PerspectiveCamera(
75, // угол обзора (FOV)
window.innerWidth / window.innerHeight, // соотношение сторон
0.1, // ближняя плоскость отсечения
1000 // дальняя плоскость отсечения
);
camera.position.set(0, 1, 5); // камера смотрит с точки (0, 1, 5)
Рендерер — это компонент, который переводит сцену и камеру в пиксели, т.е. отрисовывает результат на HTML-экране. Более подробно разберем во 2 части статьи.
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight); // размеры вьюпорта
document.body.appendChild(renderer.domElement); // <canvas> элемент, вставляемый в DOM
Как они работают вместе ?
Ты → создаёшь объекты → добавляешь их в сцену
Камера → “смотрит” на сцену
Рендерер → рисует это в на экране
Так а что же на счет 3d моделей ради которых мы и собрались? Давай разберем их чуть подробнее.
Основные части модели
Что же такое модель ?
3D-модель — это структура, описывающая форму, материалы, текстуры и поведение объекта.
Как ты уже понял по описанию сущность состоит из нескольких компонентов. Давай разберемся в них подробнее.
Геометрия (Geometry) - это форма модели: вершины, грани, координаты и нормали.
Вершины (vertices) — точки в 3D-пространстве
Грани (faces) — треугольники между вершинами
Нормали — направление, в которое “смотрит” поверхность
UV — координаты наложения текстур
Более подробно разберем во 2 части статьи
Материалы (Materials) - описывают, как должна выглядеть поверхность: цвет, отражения, прозрачность.
В Threejs есть множество материалов, которые служат абстракцией для наилучшего описания нужного материла. Основной MeshStandardMaterial:
const standardMaterial = new THREE.MeshStandardMaterial({
color: 0xffffff,
metalness: 0.8,
roughness: 0.2
});
MeshStandardMaterial
, поддерживает следующие параметры:
color
roughness
metalness
emissive
alpha (прозрачность)
Для более продвинутых кейсов также существует MeshPhysicalMaterial
, данный материал отличается более реалистичным отображением и фактически существует только в рамках threejs, к нему может быть автоматически преобразован материал модели с настройками отражения.
Текстуры (Textures) - это изображения, которые накладываются на материал для создания реалистичности.
Типы текстур:
diffuse
/baseColor
— основной цветnormalMap
— фейковая детализация рельефаmetalnessMap
,roughnessMap - блеск
aoMap
— ambient occlusion (тени)emissiveMap
— подсветка
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('/textures/wood.jpg');
const material = new THREE.MeshStandardMaterial({ map: texture });
Загрузка модели
Загрузка моделей может отличаться в зависимости от формата самой модели. Однако для наиболее популярных форматов подойдет GLTFLoader
. В случае более экзотических форматов можно использовать Loader
с кастомным поведением
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
const loader = new GLTFLoader();
loader.load('/models/robot.glb', (gltf) => {
scene.add(gltf.scene);
});
Загрузка анимации
Каждая модель может содержать анимацию, если она была заложена на этапе создания этой модели 3d-дизайнером.
В рамках threejs это можно проверить если модель содержит анимации (gltf.animations.length > 0
), используй THREE.AnimationMixer
:
let mixer;
const clock = new THREE.Clock();
loader.load('/models/fox.glb', (gltf) => {
const model = gltf.scene;
scene.add(model);
mixer = new THREE.AnimationMixer(model);
// Проигрываем первую анимацию
const action = mixer.clipAction(gltf.animations[0]);
action.play();
});
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
mixer?.update(delta);
renderer.render(scene, camera);
}
Threejs и React
Для работы с Three.js в React чаще всего используется следующие пакеты:
@react-three/fiber - обертка над Three.js через JSX (аналог react-dom, но для WebGL)
@react-three/drei - Набор готовых компонентов: OrbitControls, Stage, Text, Gizmo, Loader и т.д.
@react-three/postprocessing - Эффекты постобработки (bloom, depth of field, glitch и пр.)
import { Canvas } from '@react-three/fiber';
import { OrbitControls, Stage } from '@react-three/drei';
export default function App() {
return (
<Canvas>
<Stage environment="city" intensity={0.6}>
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="skyblue" />
</mesh>
</Stage>
<OrbitControls />
</Canvas>
);
}
Как видно из примера буквально в одну строчку кода можно описать нужное поведение. Например OrbitControls
позволяет вращать камеру относительно сцены. А Stage
добавляет пресет заднего фона с освещением. Работа с моделями также упрощена все настройки оборачиваются в mesh и внутри него описываются геометрия и материал, то есть составные части модели.
Также добавлен хук для упрощенной загрузки моделей - useGLTF
// ModelViewer.jsx
import { useGLTF } from '@react-three/drei';
export default function ModelViewer(props) {
const { scene } = useGLTF('/models/robot.glb');
return <primitive object={scene} scale={1.5} {...props} />;
}
Далее можно вставить данную компоненту прямо в сцену как и любую другую компоненту в обычном react приложении.
Кроме того добавлен хук для загрузки текстур - useTextures
// CrateModel.jsx
import { useGLTF, useTexture } from '@react-three/drei';
import * as THREE from 'three';
export default function CrateModel(props) {
// Загружаем модель
const { nodes } = useGLTF('/models/crate.glb');
// Загружаем текстуры
const textureProps = useTexture({
map: '/textures/crate_diffuse.jpg',
roughnessMap: '/textures/crate_roughness.jpg',
normalMap: '/textures/crate_normal.jpg',
});
// Настройка обёртки текстур (по желанию)
Object.values(textureProps).forEach((tex) => {
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
tex.repeat.set(1, 1);
});
return (
<mesh
geometry={nodes.Crate.geometry}
{...props}
castShadow
receiveShadow
>
<meshStandardMaterial
{...textureProps}
metalness={0.1}
roughness={1}
/>
</mesh>
);
}
Мы разобрали базу, без которой дальше никуда. Я надеюсь как минимум избавил тебя от переживаний, что работа с моделями это что-то из жанра фантастики и все намного проще чем кажется, если разобраться в ключевых аспектах.
В следующей части копнём глубже: как работает сам WebGL под капотом, что на самом деле делает Three.js и как всё это грамотно оптимизировать, чтобы сцена не лагала даже на мобилках. Будет интересно.
Комментарии (5)
jeny_tat
16.07.2025 07:01Искала золото, нашла бриллиант. Как раз начала интересоваться данной библиотекой. Не знаю будет продолжение или нет, но тема очень интересная
AlanNabiev Автор
16.07.2025 07:01Спасибо, уже работаю над продолжением с подробным объяснением работы threejs с WebGL
amXCVI
16.07.2025 07:01Очень жду продолжение
Особенно круто было бы почитать про реализацию web AR
AlanNabiev Автор
16.07.2025 07:01Спасибо, очень интересная тема обязательно рассмотрю ее в будущих статьях
cmyser
Супер, жду продолжения