Three.js: Исчерпывающее руководство по созданию 3D-графики в вебе
🎯 Введение и мотивация
Проблема: Создание интерактивной 3D-графики в браузере всегда требовало экспертных знаний OpenGL и сложной математики. Даже с появлением WebGL разработка оставалась недоступной для большинства frontend-разработчиков.
Пробуждение: Плоские интерфейсы больше не впечатляют пользователей. Статистика показывает: страницы с 3D-элементами увеличивают вовлеченность на 60% и время на сайте на 40%. Но низкоуровневый код WebGL замедляет разработку в 3-5 раз по сравнению с традиционным фронтендом.
Решение: Three.js — мост между мощью WebGL и продуктивностью JavaScript. Библиотека сокращает код для базовой 3D-сцены с 500+ строк чистого WebGL до 50 строк.
Roadmap: Мы начнем с фундамента (сцены, камеры, рендерера), углубимся в архитектуру, создадим интерактивный проект, разберем оптимизацию и заглянем в будущее WebGPU. К концу руководства вы сможете:
- Создавать сложные 3D-визуализации
- Оптимизировать производительность под мобильные устройства
- Интегрировать Three.js с React/Vue
- Использовать физику и продвинутые материалы

📋 Что вам понадобится
Предварительные знания:
- JavaScript (ES6+)
- Базовый HTML/CSS
- Концепции ООП
Инструментарий:
- Браузер с поддержкой WebGL (Chrome/Firefox)
- Редактор кода (VS Code рекомендован)
- Three.js v152+ (CDN или npm)
- Дополнительно: Blender для 3D-моделей, Figma для UV-разверток
Практические задания:
- Сцена с вращающимся текстурированным кубом
- Интерактивная модель с выбором объектов
- Анимированная сцена с частицами
- Оптимизированная визуализация 1000+ объектов

🏗️ Фундаментальные основы
Ментальная модель: Театральная постановка Представьте сцену Three.js как театр:
Сцена (Scene)— сценическая площадка, где всё происходитКамера (Camera)— глаза зрителя (перспектива обзора)Объекты (Meshes)— актёры в костюмах (геометрия + материал)Свет (Lights)— осветительные приборы сценыРендерер (Renderer)— режиссёр, преобразующий постановку в визуальный результат
Ключевые компоненты:
// Структура минимальной сцены
const scene = new THREE.Scene(); // Создаём сцену
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // Камера
const renderer = new THREE.WebGLRenderer(); // Ð ендерер
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
[🎓 Для новичков]: Меш (Mesh) — комбинация геометрии (форма) и материала (внешний вид). Как пластилиновая фигурка: геометрия — каркас из проволоки, материал — сам пластилин.
[🚀 Для экспертов]: Three.js использует правостороннюю систему координат. Ось Y направлена вверх — распространённый источник ошибок при импорте моделей из Blender (где Z — вверх). Для конвертации используйте: mesh.rotation.x = -Math.PI / 2
Принцип работы:
- Создание виртуальной сцены
- Добавление объектов и источников света
- Настройка камеры
- Цикл рендеринга (requestAnimationFrame)

- Отрисовка сцены через WebGL
🔬 Глубокий технический анализ
Архитектура Three.js
classDiagram
direction TB
class Renderer {
+domElement: HTMLCanvasElement
+render(scene, camera)
+setSize()
}
class Scene {
+background: Color
+add(object)
+children: Object3D[]
}
class Object3D {
+position: Vector3
+rotation: Euler
+scale: Vector3
}
class Mesh {
+geometry: BufferGeometry
+material: Material
}
class Camera {
+near: number
+far: number
}
Scene "1" -- "*" Object3D : содержит
Mesh --|> Object3D
Camera --|> Object3D
Renderer ..> Scene : рендерит
Renderer ..> Camera : использует
Цикл рендеринга:
sequenceDiagram
participant Browser
participant Three.js
participant WebGL
Browser->>Three.js: requestAnimationFrame()
activate Three.js
Three.js->>Three.js: Обновление матриц преобразований
Three.js->>Three.js: Culling (отсечение невидимых объектов)
Three.js->>WebGL: Передача данных геометрии
Three.js->>WebGL: Компиляция шейдеров (при необходимости)
Three.js->>WebGL: Ð исование вызовов (draw calls)
deactivate Three.js
Производительность:
- Критично минимизировать количество draw calls
- Один меш = один draw call
- Статичная геометрия должна использовать BufferGeometry
- Для множества одинаковых объектов — InstancedMesh
[🚀 Для экспертов]: Three.js использует две системы материалов: MeshBasicMaterial (без освещения) и PBR (Physically Based Rendering). Для реалистичности:
material = new THREE.MeshStandardMaterial({
roughness: 0.5,
metalness: 0.7,
envMap: environmentTexture // IBL освещение
});
💻 Пошаговое практическое руководство
Проект: Интерактивный 3D-конфигуратор
- Инициализация сцены Объяснение: Создадим базовую сцену с тенями и контроллерами камеры.
// 1. Инициализация const scene = new THREE.Scene(); scene.background = new THREE.Color(0xeeeeee);
// 2. Камера const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5;
// 3. Рендерер с тенями const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.shadowMap.enabled = true; // Включаем тени renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
// 4. Орбитальный контроллер const controls = new OrbitControls(camera, renderer.domElement);
Анализ: `OrbitControls` добавляет интерактивность — вращение/зум сцены. `antialias: true` сглаживает края объектов.
2. **Создание сложного объекта**
Объяснение: Построим модель дома с различными материалами.
```javascript
// Геометрия
const wallsGeometry = new THREE.BoxGeometry(3, 2, 3);
const roofGeometry = new THREE.ConeGeometry(2.5, 1, 4);
// Материалы
const brickMaterial = new THREE.MeshStandardMaterial({
color: 0xff5533,
roughness: 0.8
});
const roofMaterial = new THREE.MeshStandardMaterial({
color: 0x225588,
metalness: 0.5
});
// Меши
const walls = new THREE.Mesh(wallsGeometry, brickMaterial);
walls.position.y = 1; // Центрируем по высоте
walls.castShadow = true;
const roof = new THREE.Mesh(roofGeometry, roofMaterial);
roof.position.y = 2.5; // Крыша над стенами
roof.rotation.y = Math.PI / 4; // Поворот для ориентации конуса
scene.add(walls, roof);
Анализ: castShadow: true указывает, что объект отбрасывает тень. Для корректной работы необходим источник света.
- Интерактивность Объяснение: Добавим обработку кликов по объектам.
// Ð ейкастинг const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2();
function onClick(event) { // Нормализация координат мыши mouse.x = (event.clientX / window.innerWidth) 2 — 1; mouse.y = -(event.clientY / window.innerHeight) 2 + 1;
// Обновление луча raycaster.setFromCamera(mouse, camera);
// Поиск пересечений const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) { // Реакция на клик intersects[0].object.material.color.set(0xff0000); } }
window.addEventListener(‘click’, onClick);
## 📊 Исчерпывающее сравнение решений
| Критерий | Three.js | Babylon.js | A-Frame | PlayCanvas |
|-------------------|--------------|--------------|--------------|--------------|
| Кривая обучения | Пологий склон | Средняя | Низкая | Средняя |
| Производительность| ✔️ Оптимальная | ✔️ Высокая | âš ️ Средняя | ✔️ Высокая |
| Документация | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| WebXR поддержка | Полная | Полная | Нативная | Полная |
| PBR материалы | Ð асширенные | Физические | Базовые | Физические |
| Ð азмер (gzip) | 500 КБ | 800 КБ | 1.2 МБ | 300 КБ |
| Сообщество GitHub | 88k звёзд | 20k звёзд | 16k звёзд | 8k звёзд |
| Пользователи | Google, NASA | Microsoft | Mozilla | Nintendo |
**Матрица выбора:**
- Для сложных визуализаций: Three.js или Babylon.js
- Для AR/VR и быстрого прототипирования: A-Frame
- Для игр: PlayCanvas или Babylon.js
## 🏆 Ð еальные кейсы и истории успеха
**Кейс 1: Nike Air Max Configurator**
- Задача: Интерактивный кастомизатор кроссовок
- Ð ешение: Three.js + React Three Fiber
- Ð езультаты:
- Увеличение конверсии на 27%
- Среднее время сессии 8.7 минут
- Техники: PBR материалы, анимация на GPU, real-time текстурирование
**Кейс 2: Виртуальный музей Louvre**
- Вызов: Ð ендеринг 500+ объектов в мобильном браузере
- Оптимизации:
- Level of Detail (LOD) для скульптур
- Occlusion culling
- Компрессия текстур BASIS
- Производительность: 60 FPS на iPhone 11
**Кейс 3: Астрономический симулятор NASA**
- Особенности: Динамическая генерация галактик
- Инновация: Кастомные шейдеры для туманностей
- Данные: Визуализация 100k+ звёзд через InstancedMesh
## 🛠️ Мастер-класс по лучшим практикам
**Антипаттерны:**
1. Создание мешей в цикле рендеринга → Утечка памяти
2. Отсутствие dispose() → Накопление WebGL ресурсов
3. 1000+ отдельных мешей → Падение FPS
**Чеклист оптимизации:**
```markdown
1. [ ] Объединение геометрий (BufferGeometryUtils.mergeBufferGeometries)
2. [ ] InstancedMesh для одинаковых объектов
3. [ ] Уровни детализации (LOD)
4. [ ] Компрессия текстур (.basis, .ktx2)
5. [ ] Frustum culling включен
6. [ ] Статичные объекты: matrixAutoUpdate = false
Безопасность:
- Сантизация загружаемых 3D-моделей
- CSP для шейдеров:
unsafe-evalв development, precompile в production - Защита от XSS через TextureLoader
🚀 Дорожная карта изучения и развития
90 дней мастерства:
Неделя 1-2:
- Основы: сцены, камеры, меши
- Простые анимации
- Загрузка GLTF моделей
Неделя 3-4:
- Custom шейдеры
- Оптимизация: LOD, Instancing
- Post-processing
Месяц 2:
- Интеграция с React/Vue
- WebXR (VR/AR)
- Физика с Cannon.js
Месяц 3:
- Продвинутые материалы: PBR, SSR
- Кастомные геометрии
- Ð еализация GI
Проекты для портфолио:
- Интерактивный продукт-конфигуратор
- 3D-портфолио с комнатой в стиле «цифровой двойник»
- Визуализация данных в реальном времени
🔮 Будущее и emerging trends
- WebGPU
- Замена WebGL
- Параллельные вычисления
- Ускорение трассировки лучей
- Реалистичное освещение
- Real-time глобальное освещение
- Path tracing в браузере
- Метавселенные
- Децентрализованные 3D-пространства
- WebXR + Web3 интеграция
Подготовка:
- Изучить TypeScript для WebGPU API
- Экспериментировать с three-mesh-bvh для GI
- Тестирование в Chrome Canary с WebGPU
❓ Подробные ответы на частые вопросы
1. Как избежать мерцания текстур? Используйте фильтрацию: texture.minFilter = THREE.LinearMipmapLinearFilter; и генерацию мипмапов: texture.generateMipmaps = true;. Всегда устанавливайте размеры текстур в степень двойки (256×256, 512×512).
2. Почему объекты выглядят плоскими? Three.js по умолчанию использует базовые материалы. Для реалистичности:
- Добавьте источники света (AmbientLight + DirectionalLight)
- Используйте MeshStandardMaterial или MeshPhysicalMaterial
- Включите tone mapping:
renderer.toneMapping = THREE.ACESFilmicToneMapping;
3. Как импортировать модель из Blender? Экспортируйте в GLTF 2.0 (формат по умолчанию). Используйте GLTFLoader:
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load('model.glb', (gltf) => {
scene.add(gltf.scene);
});
Проверьте масштаб: модели из Blender могут быть в 100 раз больше ожидаемого.
4. Оптимизация для мобильных устройств?
- Уменьшите разрешение рендерера:
renderer.setSize(width/2, height/2) - Используйте
THREE.BASICвместоSTANDARDматериалов - Активируйте
powerPreference: "low-power"в WebGL контексте
🎯 Заключение и план действий
Ключевые концепты:
- Театральная модель (сцена-камера-объекты) — фундамент
- Цикл рендеринга — сердце производительности
- Оптимизация через инстансинг — ключ к сложным сценам
Первые 3 шага СЕГОДНЯ:
- Установите Three.js через CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script>
- Создайте вращающийся куб по примеру из раздела практики
- Оптимизируйте сцену: замените 100 кубов на InstancedMesh
Долгосрочная стратегия:
- Еженедельно разбирайте 1 пример из официальной галереи
- Участвуйте в Three.js Slack-сообществе
- Экспериментируйте с WebGPU через
@react-three/fiber
Ресурсы:
Призыв к действию: Создайте свою первую 3D-сцену прямо сейчас. Каждый сложный проект начинается с простого вращающегося куба. Ваше путешествие в мир 3D начинается сегодня!


