Введение в Three.js: создаем 3D графику в браузере с нуля
#Веб-разработка #Основы JavaScript #Canvas и SVGДля кого эта статья:
- Веб-разработчики, желающие освоить 3D-графику для своих проектов
- Студенты и начинающие программисты, интересующиеся JavaScript и 3D-технологиями
- Профессионалы из сферы электронной коммерции и дизайна, стремящиеся улучшить пользовательский опыт через интерактивные элементы
Представьте: ваш веб-сайт внезапно выходит в третье измерение, позволяя посетителям вращать продукты, исследовать виртуальные пространства или взаимодействовать с интерактивными 3D-моделями — всё это прямо в браузере, без плагинов. 🚀 Интригует? Тогда Three.js станет вашим проводником в мир веб-3D. В отличие от традиционных сложных 3D-инструментов, требующих месяцы освоения, Three.js демократизирует трехмерную графику, делая её доступной для любого веб-разработчика со знанием JavaScript. Давайте вместе сделаем первые шаги в этой увлекательной технологии и создадим впечатляющую 3D-сцену буквально с нуля.
Что такое Three.js и почему он нужен веб-разработчикам
Three.js — это JavaScript-библиотека, которая абстрагирует сложности работы с WebGL, предоставляя разработчикам более интуитивно понятный и простой API для создания 3D-графики в браузере. Разработанная Рикардо Кабелло (известным как Mr.doob) в 2010 году, эта библиотека превратилась в стандарт де-факто для 3D-визуализации в вебе.
Михаил Соколов, технический директор
Мой первый опыт с Three.js был весьма показательным. Клиент, производитель премиальной мебели, хотел обычный онлайн-каталог, но я предложил нечто большее — конфигуратор, где посетители могли бы видеть изделия в 3D, менять материалы и расцветки. «Это же потребует месяцы разработки и серьезный бюджет», — возразил клиент. За выходные я собрал прототип на Three.js, где можно было вращать диван и менять обивку в реальном времени. Когда в понедельник я продемонстрировал результат, в переговорной повисла тишина, а затем последовало: «Сколько нужно времени на полноценную реализацию?» Конверсия на сайте после внедрения выросла на 34%, а средний чек — на 18%. Клиенты стали проводить на сайте в среднем на 4 минуты больше, взаимодействуя с 3D-моделями.
Почему же веб-разработчики должны обратить внимание на Three.js? Давайте рассмотрим ключевые преимущества:
- Доступность для веб-платформы — работает в любом современном браузере без установки дополнительных плагинов
- Низкий порог входа — если вы знаете JavaScript, вы уже можете начать работу с Three.js
- Высокая производительность — оптимизирован для эффективного использования ресурсов браузера
- Обширная экосистема — множество готовых компонентов, расширений и примеров кода
- Активное сообщество — постоянные обновления и поддержка
| Сфера применения | Примеры использования Three.js | Преимущества |
|---|---|---|
| Электронная коммерция | 3D-модели товаров, конфигураторы продуктов | Увеличение конверсии на 15-30% |
| Образование | Интерактивные 3D-модели для обучения | Улучшение усвоения материала до 60% |
| Игровая индустрия | Браузерные 3D-игры | Доступность на любых устройствах |
| Архитектура | Визуализации зданий, виртуальные туры | Наглядность и интерактивность проектов |
Three.js выступает абстракцией над WebGL — низкоуровневым API для рендеринга 3D-графики в браузере. Работать напрямую с WebGL может быть сложно из-за необходимости написания шейдеров и понимания графического конвейера. Three.js берет на себя большую часть этой сложности, позволяя сосредоточиться на творческой составляющей.

Установка и настройка первого Three.js проекта
Начать работу с Three.js проще, чем может показаться. Для установки у вас есть несколько вариантов — от быстрого подключения через CDN до полноценной интеграции через npm для более сложных проектов. 📦
Вот наиболее распространенные способы установки:
- Через CDN (самый быстрый способ для экспериментов):
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
- Через npm (для проектов с использованием сборщиков):
npm install three
Затем импортируйте библиотеку в ваш проект:
import * as THREE from 'three';
Теперь давайте создадим базовый шаблон проекта. Для начала работы с Three.js вам понадобится HTML-документ со следующей структурой:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My First Three.js Scene</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
<script>
// Здесь будет ваш код Three.js
</script>
</body>
</html>
Давайте напишем самый простой сценарий для отображения вращающегося куба — классический "Hello World" в мире 3D-графики:
// Создаем сцену
const scene = new THREE.Scene();
// Создаем камеру
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// Создаем рендерер
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Создаем геометрию куба
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Анимация
function animate() {
requestAnimationFrame(animate);
// Вращение куба
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
| Проблема при установке | Возможная причина | Решение |
|---|---|---|
| Пустой экран | Неверный путь к библиотеке | Проверьте консоль браузера и URL в теге script |
| Ошибки в консоли | Несовместимая версия браузера | Используйте современный браузер с поддержкой WebGL |
| Низкая производительность | Слишком сложная сцена | Оптимизируйте геометрию или используйте LOD |
| Искажения при ресайзе окна | Не обновляются параметры камеры и рендерера | Добавьте обработчик события window.resize |
После запуска этого кода вы должны увидеть зеленый вращающийся каркасный куб на черном фоне. Поздравляем — вы только что создали свою первую 3D-сцену с помощью Three.js! 🎉
Основные элементы Three.js: сцена, камера и рендеринг
Чтобы эффективно работать с Three.js, необходимо понимать три фундаментальных компонента, образующих основу любого 3D-проекта: сцену, камеру и рендерер. Эти элементы формируют классическую трехмерную "сцену" — метафору, знакомую всем, кто хотя бы немного интересовался кинематографом или театром. 🎬
Сцена (Scene)
Сцена в Three.js — это контейнер, который содержит все объекты вашего 3D-мира: модели, источники света, камеры и другие элементы. Её можно представить как съемочную площадку, где расставлены все необходимые для создания визуального эффекта элементы.
const scene = new THREE.Scene();
// Опционально можно задать фон сцены
scene.background = new THREE.Color(0x87CEEB);
// Или использовать изображение в качестве фона
// const textureLoader = new THREE.TextureLoader();
// scene.background = textureLoader.load('sky.jpg');
Камера (Camera)
Камера определяет, что именно увидит пользователь. В Three.js доступно несколько типов камер, но наиболее часто используются две:
- PerspectiveCamera — эмулирует зрение человека с эффектом перспективы (объекты вдали выглядят меньше)
- OrthographicCamera — обеспечивает вид без перспективного искажения, полезна для изометрических или технических изображений
// Перспективная камера (угол обзора, соотношение сторон, ближняя плоскость отсечения, дальняя плоскость)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5); // Расположение камеры по осям X, Y, Z
camera.lookAt(0, 0, 0); // Куда смотрит камера
Рендерер (Renderer)
Рендерер — это компонент, который фактически визуализирует вашу сцену с выбранной камеры на HTML-элементе canvas. В большинстве случаев используется WebGLRenderer, так как он обеспечивает наилучшую производительность и поддерживается всеми современными браузерами.
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio); // Для четкости на Retina-дисплеях
document.body.appendChild(renderer.domElement);
// Включаем тени (если необходимо)
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Мягкие тени
Важно понимать взаимосвязь этих компонентов: сцена содержит все объекты, камера определяет, какую часть сцены мы видим, а рендерер преобразует это трёхмерное представление в двумерное изображение на экране пользователя.
Алексей Дмитриев, фронтенд-разработчик
Когда я только начинал работать с Three.js, меня постигла классическая проблема новичков — "чёрный экран отчаяния". Потратил почти два дня, проверяя каждую строчку кода, но сцена оставалась пустой. Всё изменил один момент: в отладчике я заметил, что объекты на самом деле создаются, но камера смотрит не в ту сторону! Оказывается, я разместил модель в точке (0,0,0), а камеру тоже поставил туда же, направив её вдоль оси Z. Естественно, камера "смотрела сквозь" объект. Как только я сдвинул камеру назад по оси Z — волшебным образом появилась моя модель. С тех пор я всегда использую вспомогательные объекты (helpers) для отладки камеры и осей, что сэкономило мне бесчисленные часы на поиск ошибок. Если ваша сцена пуста — первым делом проверьте, туда ли смотрит ваша камера!
Для завершения основной настройки необходимо создать функцию анимации, которая будет вызывать рендеринг сцены:
function animate() {
requestAnimationFrame(animate); // Запрашиваем следующий кадр анимации
// Здесь можно обновлять положение/состояние объектов
renderer.render(scene, camera); // Отрисовываем сцену
}
animate(); // Запускаем цикл анимации
Адаптация сцены к изменению размеров окна — важный аспект для создания отзывчивого 3D-опыта:
window.addEventListener('resize', () => {
// Обновляем размеры
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
Создание и манипуляция 3D объектами в Three.js
После настройки базовой сцены самое время населить её объектами. В Three.js объекты состоят из двух основных компонентов: геометрии (форма) и материала (визуальные свойства). Объединение геометрии и материала создаёт Mesh — визуальный 3D-объект, который можно добавить в сцену. 🧩
Разберем процесс создания различных объектов шаг за шагом:
Геометрии
Three.js предоставляет множество встроенных геометрий — от простых примитивов до сложных параметрических форм:
// Базовые примитивы
const boxGeometry = new THREE.BoxGeometry(1, 1, 1); // куб
const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32); // сфера
const cylinderGeometry = new THREE.CylinderGeometry(0.5, 0.5, 1, 32); // цилиндр
const torusGeometry = new THREE.TorusGeometry(0.5, 0.2, 16, 100); // тор (бублик)
const planeGeometry = new THREE.PlaneGeometry(10, 10); // плоскость
Материалы
Материалы определяют, как объект выглядит — его цвет, текстуру, прозрачность, блеск и другие свойства:
// Основные типы материалов
const basicMaterial = new THREE.MeshBasicMaterial({
color: 0xff0000, // красный цвет
wireframe: true // отображать только каркас
});
const phongMaterial = new THREE.MeshPhongMaterial({
color: 0x049ef4, // синий цвет
shininess: 100, // блеск
specular: 0xffffff // цвет блика
});
// Создание материала с текстурой
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('texture.jpg');
const texturedMaterial = new THREE.MeshStandardMaterial({
map: texture,
roughness: 0.4,
metalness: 0.7
});
Создание и добавление объектов в сцену
Объединяем геометрию и материал в mesh-объект и добавляем его в сцену:
// Создание объекта-меша
const cube = new THREE.Mesh(boxGeometry, phongMaterial);
cube.position.set(0, 0, 0); // Позиция объекта
cube.rotation.set(0, Math.PI / 4, 0); // Поворот объекта (в радианах)
cube.scale.set(1.5, 1, 1); // Масштаб объекта
// Добавление объекта в сцену
scene.add(cube);
Для более сложных сцен полезно группировать объекты:
// Создание группы объектов
const group = new THREE.Group();
// Добавление объектов в группу
const sphere1 = new THREE.Mesh(sphereGeometry, phongMaterial.clone());
sphere1.position.x = -2;
group.add(sphere1);
const sphere2 = new THREE.Mesh(sphereGeometry, phongMaterial.clone());
sphere2.position.x = 2;
group.add(sphere2);
// Добавление всей группы в сцену
scene.add(group);
// Теперь можно манипулировать всей группой
group.rotation.y = Math.PI / 4;
Манипуляция объектами
После создания объектов вы можете динамически изменять их положение, вращение и масштаб:
function animate() {
requestAnimationFrame(animate);
// Вращение куба
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// Изменение положения по синусоиде
sphere1.position.y = Math.sin(Date.now() * 0.001) * 0.5;
renderer.render(scene, camera);
}
Более сложные трансформации можно реализовать с помощью матрицы:
// Установка позиции, вращения и масштаба через матрицу
const matrix = new THREE.Matrix4();
matrix.compose(
new THREE.Vector3(1, 0, 0), // позиция
new THREE.Quaternion().setFromEuler( // вращение
new THREE.Euler(0, Math.PI/2, 0)
),
new THREE.Vector3(2, 2, 2) // масштаб
);
cube.matrix = matrix;
cube.matrixAutoUpdate = false; // Отключаем автообновление матрицы
Понимание системы координат Three.js критически важно для правильного размещения объектов:
- X — ось, направленная вправо
- Y — ось, направленная вверх
- Z — ось, направленная из экрана к зрителю
Для создания более реалистичных сцен необходимо добавить освещение:
// Добавление направленного света (как солнце)
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 7);
scene.add(directionalLight);
// Добавление окружающего света (рассеянный свет)
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
Интерактивность и анимация в Three.js: оживляем сцену
Интерактивность и анимация превращают статичную 3D-модель в захватывающий опыт для пользователя. Three.js предлагает множество инструментов для создания динамичных сцен, реагирующих на действия пользователя. 🕹️
Базовая анимация
Самый простой способ создать анимацию — изменять свойства объектов в цикле рендеринга:
function animate() {
requestAnimationFrame(animate);
// Анимация вращения
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// Пульсация размера
const scale = Math.sin(Date.now() * 0.001) * 0.5 + 1;
sphere.scale.set(scale, scale, scale);
renderer.render(scene, camera);
}
animate();
Контроль времени анимации
Для более предсказуемой анимации, не зависящей от частоты кадров, используйте Clock:
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // время в секундах с последнего кадра
const elapsedTime = clock.getElapsedTime(); // общее прошедшее время
// Постоянная скорость вращения независимо от FPS
cube.rotation.x += 1 * delta; // 1 радиан в секунду
// Анимация с использованием общего времени
sphere.position.y = Math.sin(elapsedTime) * 2;
renderer.render(scene, camera);
}
Взаимодействие с пользователем
Добавление обработчиков событий позволяет создавать интерактивные сцены:
// Отслеживание движения мыши
document.addEventListener('mousemove', (event) => {
// Преобразование координат мыши в нормализованные (-1 до 1)
const mouseX = (event.clientX / window.innerWidth) * 2 – 1;
const mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
// Использование координат для управления камерой или объектами
camera.position.x = mouseX * 3;
camera.position.y = mouseY * 3;
camera.lookAt(scene.position);
});
// Отслеживание кликов
document.addEventListener('click', (event) => {
// Вычисляем позицию мыши в нормализованных координатах
const mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 – 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// Raycaster для определения пересечений луча с объектами
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
// Находим пересечения
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
// Действие при клике на объект
const clickedObject = intersects[0].object;
clickedObject.material.color.set(0xff0000); // меняем цвет на красный
}
});
Органы управления камерой
Three.js предлагает готовые контроллеры для управления камерой. OrbitControls — один из самых популярных:
// Необходимо импортировать OrbitControls
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// Создаем контроллер
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // плавное движение
controls.dampingFactor = 0.05;
controls.minDistance = 3; // минимальное расстояние приближения
controls.maxDistance = 10; // максимальное расстояние удаления
// В цикле анимации обновляем контроллер
function animate() {
requestAnimationFrame(animate);
controls.update(); // Обновление контроллера
renderer.render(scene, camera);
}
Продвинутая анимация с GSAP
Для более сложных анимаций можно использовать библиотеку GSAP (GreenSock Animation Platform):
// Импортируем GSAP
import gsap from 'gsap';
// Анимация с использованием timeline
const timeline = gsap.timeline({ repeat: -1, yoyo: true });
timeline.to(cube.position, {
x: 2,
duration: 1,
ease: "power2.inOut"
}).to(cube.rotation, {
y: Math.PI * 2,
duration: 2,
ease: "elastic.out(1, 0.3)"
}, "-=0.5").to(cube.scale, {
x: 2,
y: 0.5,
z: 2,
duration: 1,
ease: "back.inOut(1.7)"
});
| Тип анимации | Сложность реализации | Производительность | Применение |
|---|---|---|---|
| Ручная анимация в requestAnimationFrame | Низкая | Высокая | Простые, повторяющиеся движения |
| Анимация через GSAP | Средняя | Высокая | Сложные последовательности с точным таймингом |
| Скелетная анимация | Высокая | Средняя | Персонажи, сложные объекты |
| Физическая анимация (Cannon.js, Ammo.js) | Высокая | Низкая-средняя | Реалистичное движение, симуляции |
Для более оптимальной производительности при анимации сложных сцен, рассмотрите эти советы:
- Используйте InstancedMesh для анимации множества одинаковых объектов
- Применяйте LOD (Level of Detail) для снижения детализации удаленных объектов
- Избегайте пересоздания геометрий и материалов в цикле анимации
- Используйте Object3D.traverse() для эффективного обхода иерархии объектов
- Отключайте ненужные обновления с помощью object.matrixAutoUpdate = false для статичных объектов
Three.js открывает впечатляющие возможности для создания интерактивной 3D-графики в браузере даже для тех, кто раньше не имел опыта в трехмерном программировании. Освоив базовые компоненты — сцену, камеру, рендерер, а также научившись создавать и анимировать объекты, вы получаете инструмент для реализации любых творческих идей в вебе. Помните: лучший способ изучить Three.js — это эксперименты и практика, не бойтесь модифицировать примеры и создавать собственные уникальные 3D-интерфейсы, которые выделят ваши проекты среди конкурентов и подарят пользователям незабываемые впечатления.
Станислав Плотников
фронтенд-разработчик