Three.js — это библиотека JavaScript для создания 3D-графики в браузере на основе WebGL. Она позволяет добавлять интерактивные элементы на сайт без необходимости писать код с нуля на уровне OpenGL. Главное отличие от стандартных библиотек: Three.js предоставляет готовый слой абстракции над сложными API графики, упрощая работу со сценами, камерой и материалами. Это не просто визуальный эффект, а инструмент для создания полноценных интерактивных интерфейсов, где пользователь может вращать модели, менять параметры или взаимодействовать с объектами напрямую.
Введение: роль Three.js в веб-разработке и отличие от стандартных библиотек
Three.js — это библиотека JavaScript для создания 3D-графики в браузере на основе WebGL. Она позволяет добавлять интерактивные элементы на сайт без необходимости писать код с нуля на уровне OpenGL.
Главное отличие от стандартных библиотек: Three.js предоставляет готовый слой абстракции над сложными API графики, упрощая работу со сценами, камерой и материалами. Это не просто визуальный эффект, а инструмент для создания полноценных интерактивных интерфейсов, где пользователь может вращать модели, менять параметры или взаимодействовать с объектами напрямую.
В отличие от CSS-анимаций или простых SVG, Three.js работает с геометрией, текстурными координатами и шейдерами. Это позволяет создавать сложные физические симуляции, процедурную генерацию и интерактивные данные-визуализации.
Шаг 1. Подготовка окружения: установка зависимостей и базовая конфигурация проекта
Для работы с Three.js не обязательно устанавливать Node.js, но использование пакетного менеджера упрощает управление версиями. Можно подключить библиотеку через CDN или npm.
Пример подключения через CDN в HTML-файле:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
Использование модулей ES6 (рекомендуемый способ):
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
Важно: современные версии Three.js используют модульную систему. Старые пути импорта могут не работать в новых сборках.
Создайте файл index.html и подключите скрипт. Убедитесь, что сервер локального развития запущен (например, через VS Code Live Server), так как браузеры блокируют загрузку модулей с диска из соображений безопасности.
Шаг 2. Создание сцены, камеры и рендерера: фундамент интерактивности
Три основных компонента любой сцены в Three.js — сцена, камера и рендерер.
Сцена (Scene) — это контейнер для всех объектов. Она хранит информацию о свете, атмосфере и других глобальных настройках.
Камера (Camera) определяет точку зрения пользователя. Стандартная PerspectiveCamera имитирует человеческое зрение с перспективой. OrthographicCamera используется для чертежей или изометрии без искажений перспективы.
Рендерер (Renderer) отвечает за отрисовку графики на элементе DOM. WebGLRenderer — стандартный выбор.
Пример кода инициализации:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
Камера должна быть помещена в сцену (scene.add(camera)), а рендерер — на страницу. Не забудьте добавить обработчик изменения размера окна, чтобы сцена не растягивалась при ресайзе браузера.
Шаг 3. Работа со светом и материалами: реализация физики и текстур
Свет делает сцену реалистичной. В Three.js есть несколько типов источников света.
AmbientLight — общий фоновый свет, заполняющий тени.
DirectionalLight — имитирует солнце, падает под углом и создает жесткие тени.
PointLight — точечный источник, светящийся во все стороны (например, лампочка).
SpotLight — прожектор с конусом света.
Материалы определяют, как объект реагирует на свет. MeshBasicMaterial не учитывает свет (всегда яркий), MeshLambertMaterial реагирует на свет мягко, MeshPhongMaterial создает блики.
Для реалистичности используйте текстуры: загрузите изображение через TextureLoader и примените его к материалу свойства map.
Пример:
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshStandardMaterial({ map: texture });
Важно: текстуры должны быть оптимизированы. Слишком большие файлы замедлят загрузку страницы.
Шаг 4. Добавление геометрии и оптимизация мешей для производительности
Геометрия (Geometry) определяет форму объекта. Простые формы: BoxGeometry, SphereGeometry, PlaneGeometry.
Для сложных моделей используйте GLTFLoader или OBJLoader. Формат .glb предпочтителен из-за меньшего размера и поддержки анимаций.
Оптимизация критична для производительности:
1. Уменьшите количество полигонов (треугольников) в моделях, если это не влияет на вид.
2. Используйте InstancedMesh для отрисовки множества одинаковых объектов (например, деревьев или коробок) за один вызов рендеринга.
3. Применяйте LOD (Level of Detail): загружайте более детальные модели только при близком расстоянии пользователя.
Пример создания куба:
const geometry = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Не забывайте добавлять объекты в сцену через scene.add(object).
Шаг 5. Реализация пользовательского ввода: обработка мыши, клавиатуры и тач-событий
Интерактивность требует обработки событий. Three.js предоставляет Raycaster — инструмент для определения пересечения луча с объектами.
Raycaster позволяет узнать, на какой объект кликнул пользователь или коснулся пальцем.
Пример кода:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseClick(event) {
// Нормализация координат мыши от -1 до 1
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) {
// Обработка клика по объекту
console.log('Клик по:', intersects[0].object.name);
}
}
document.addEventListener('click', onMouseClick);
Для мобильных устройств используйте touchstart и touchend вместо click, если нужно различать жесты.
Шаг 6. Создание анимации циклов и интерактивных состояний объектов
Анимация в Three.js происходит в цикле рендеринга, который вызывается через requestAnimationFrame.
Функция animate обновляет позицию объектов и вызывает renderer.render.
Пример:
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
renderer.render(scene, camera);
}
animate();
Интерактивные состояния: меняйте свойства объекта (цвет, прозрачность, позицию) в зависимости от действий пользователя.
Пример изменения цвета при клике:
if (intersects.length > 0) {
intersects[0].object.material.color.set(0xff0000);
}
Избегайте тяжелых вычислений внутри цикла анимации. Переносите логику в отдельные функции или используйте Web Workers для сложных расчетов.
Шаг 7. Интеграция с DOM и адаптация под мобильные устройства
Three.js работает внутри элемента <canvas>, который можно встроить в любой контейнер HTML.
Для интеграции с DOM используйте CSS для позиционирования canvas, но не пытайтесь управлять 3D-объектами через CSS. Используйте JavaScript для изменения стилей элементов интерфейса (кнопок, модальных окон) на основе данных из 3D-сцены.
Адаптация под мобильные устройства:
1. Отключите курсор мыши и используйте touch-события.
2. Уменьшите разрешение рендеринга для мобильных устройств (renderer.setPixelRatio(window.devicePixelRatio < 2 ? 1 : window.devicePixelRatio)).
3. Используйте OrbitControls для управления камерой пальцами.
4. Проверьте производительность на слабых устройствах: отключите тени, сложные материалы или пост-процессинг.
Шаг 8. Оптимизация рендеринга: frustum culling, LOD и управление памятью
Frustum Culling — автоматическое отключение объектов, находящихся за пределами видимости камеры. Three.js делает это по умолчанию.
LOD (Level of Detail) — замена детальных моделей на упрощенные при удалении пользователя.
Управление памятью:
1. Удаляйте неиспользуемые объекты из сцены (scene.remove(object)).
2. Очищайте текстуры и геометрию, если они больше не нужны.
3. Используйте dispose() для освобождения памяти в браузере.
Пример:
object.geometry.dispose();
object.material.dispose();
4. Избегайте создания новых объектов внутри цикла анимации. Создавайте их один раз и переиспользуйте.
Вопросы и ответы
Можно ли использовать Three.js на статических сайтах без сервера?
Да, если библиотека подключена через CDN. Однако для модульного импорта (import) нужен локальный сервер или сборщик типа Webpack/Vite.
Как проверить производительность 3D-сцены?
Используйте инструменты разработчика браузера (Performance tab), следите за FPS. Если падает — упростите геометрию или отключите тени.
// Пример создания сцены и куба
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Добавление света
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
// Создание куба
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
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();


