Акции и промокоды Отзывы о школах

Three.js — введение в 3D-графику в браузере

#Блог

В мире веб-разработки, где каждый день появляются новые фреймворки (и исчезают старые — привет, AngularJS), Three.js остается стабильной константой уже более десяти лет. Эта JavaScript-библиотека превращает создание 3D-графики в браузере из мучительного танца с WebGL в относительно приятное времяпрепровождение.

Если раньше для создания вращающегося кубика нужно было написать сотни строк низкоуровневого кода и погрузиться в дебри линейной алгебры, то Three.js делает это за пару десятков строк. Библиотека абстрагирует всю сложность WebGL, предоставляя разработчикам понятный API для работы с камерами, сценами, освещением и анимацией.

Популярность Три.js объясняется просто: она открывает двери в мир 3D-программирования тем, кто не готов тратить месяцы на изучение математических основ компьютерной графики. Хотите создать интерактивную визуализацию данных, простую браузерную игру или впечатляющую презентацию продукта? Three.js справится с этими задачами, не заставляя вас становиться экспертом по шейдерам.

Что такое Three.js и зачем он нужен?

Three.js — это JavaScript-библиотека, которая делает WebGL доступным для смертных. Если WebGL — это как пытаться собрать ИКEA без инструкции на языке, который вы не понимаете, то Три.js — это готовый конструктор LEGO с понятными блоками и пошаговым руководством.

skhema-threejs

Простая схема работы основных компонентов Three.js. Помогает понять, как сцена, камера, рендерер и объекты взаимодействуют друг с другом.

Библиотека предоставляет высокоуровневые инструменты для создания и отображения 3D-сцен прямо в браузере. Вы получаете готовые компоненты для работы с геометрией, материалами, освещением, анимацией и импортом сложных 3D-моделей. При этом не нужно погружаться в матричные вычисления или разбираться с буферами вершин — Три.js берет всю эту математическую магию на себя.

Возможности библиотеки впечатляют: от простых вращающихся кубиков до сложных интерактивных сцен с реалистичным освещением и физикой. Можно создавать браузерные игры (хотя для серьезных проектов лучше присмотреться к Unity или Unreal Engine), интерактивные презентации продуктов, архитектурные визуализации, образовательные симуляции и даже целые виртуальные миры.

Крупные компании активно используют библиотеку для своих веб-проектов, например, NASA в интерактивных 3D-визуализациях марсохода Perseverance.

Установка и подключение

Подключить его можно несколькими способами — от классического скачивания файлов до современных пакетных менеджеров. Выбор зависит от вашего проекта и личных предпочтений (а также от того, насколько сильно вы любите или ненавидите npm).

Установка через npm

Самый цивилизованный способ для тех, кто живет в современном мире модульной разработки:

npm install three

После установки можно импортировать всю библиотеку целиком или только нужные части — что особенно актуально, если вы заботитесь о размере бандла (а кто не заботится в 2025 году?):

// Импорт всей библиотеки

import * as THREE from 'three';

const scene = new THREE.Scene();

// Импорт только нужных компонентов

import { Scene, PerspectiveCamera, WebGLRenderer } from 'three';

const scene = new Scene();

Подключение через CDN

Для быстрого старта или простых экспериментов можно использовать CDN — правда, придется немного поплясать с import maps:

<script async src=»https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js»></script>

<script type=»importmap»>

{

«imports»: {

«three»: «https://unpkg.com/three@<version>/build/three.module.js»

}

}

</script>

<script type=»module»>

import * as THREE from ‘three’;

const scene = new THREE.Scene();

</script>

Полифилл es-module-shims нужен для старых браузеров, которые еще не поддерживают import maps нативно.

Критически важно: всегда используйте одну и ту же версию библиотеки для всех компонентов — смешивание версий может привести к неприятным сюрпризам и загадочным ошибкам, на поиск которых вы потратите больше времени, чем на написание самого кода.

Проверка поддержки WebGL

Хотя в 2025 году WebGL поддерживается практически везде (даже в браузере вашего умного холодильника), иногда встречаются древние устройства или корпоративные браузеры с отключенной аппаратной акселерацией. Проверка совместимости — это как пристегивание ремня безопасности: кажется излишним, пока не спасет вам жизнь (или репутацию).

Три.js предоставляет удобный инструмент для проверки поддержки WebGL. Подключите модуль проверки совместимости:

import { WebGL } from 'three/examples/jsm/capabilities/WebGL.js';

if (WebGL.isWebGLAvailable()) {

    // Все хорошо, можно запускать 3D-магию

    initializeThreeJS();

} else {

    // Houston, we have a problem

    const warning = WebGL.getWebGLErrorMessage();

    document.getElementById('container').appendChild(warning);

}

Функция WebGL.getWebGLErrorMessage() возвращает готовое сообщение об ошибке с рекомендациями для пользователя — от обновления браузера до включения аппаратной акселерации. Это избавляет вас от необходимости объяснять техническим языком, почему у пользователя вместо красивого 3D-куба отображается черный экран.

Альтернативный подход — graceful degradation: показывать статичное изображение или 2D-версию вашего контента для устройств без поддержки WebGL. Правда, объяснить заказчику, почему его «революционная 3D-презентация» превратилась в обычную картинку, может оказаться сложнее, чем написать сам код.

Основные компоненты

Three.js построен на четырех краеугольных камнях, без которых ваша 3D-сцена будет примерно так же функциональна, как автомобиль без колес. Понимание этих компонентов — ключ к созданию чего-то большего, чем просто черный экран с сообщением об ошибке в консоли.

Сцена (Scene)

Сцена — это виртуальная вселенная, в которой существуют все ваши 3D-объекты. Это контейнер, который хранит геометрию, источники света, камеры и все остальное, что должно быть отрендерено. Создается просто:

const scene = new THREE.Scene();

Можно думать о сцене как о театральной сцене — без неё актеры (ваши 3D-объекты) просто болтаются в пустоте.

threejs-sczena-kamera-obekt

Простая схема работы основных компонентов Three.js. Помогает понять, как сцена, камера, рендерер и объекты взаимодействуют друг с другом.

Камера (Camera)

Камера определяет, что и как видит пользователь. Три.js предлагает несколько типов камер, но чаще всего используется PerspectiveCamera — она имитирует человеческое зрение с перспективными искажениями:

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

Параметры: поле зрения (75°), соотношение сторон, ближняя и дальняя плоскости отсечения.

Рендерер (Renderer)

Рендерер — это художник, который превращает вашу 3D-сцену в пиксели на экране. WebGLRenderer — основной рабочий инструмент:

const renderer = new THREE.WebGLRenderer();

renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

Объекты (Mesh)

Mesh — это видимый объект, состоящий из геометрии (формы) и материала (внешнего вида). Это как скульптура: у неё есть форма (геометрия) и покрытие (материал) — мрамор, бронза или, в нашем случае, пиксели определенного цвета.

Эти четыре компонента работают в связке: сцена содержит объекты, камера на них смотрит, а рендерер всё это отображает. Без любого из них система рассыпается быстрее, чем обещания стартапа изменить мир.

Создание первого 3D-объекта

Пришло время создать что-то осязаемое — хотя бы в цифровом смысле. Начнем с классики жанра: зеленый куб, который стал «Hello, World!» 3D-программирования.

vrashhayushhijsya-kub

Результат выполнения кода: зелёный куб, который можно вращать в пространстве. Иллюстрация помогает понять, как будет выглядеть первый созданный объект.

Геометрия (Geometry)

Геометрия определяет форму объекта — его вершины, грани и математическое описание. BoxGeometry создает параллелепипед (или куб, если все стороны равны):

const geometry = new THREE.BoxGeometry(1, 1, 1);

Параметры — ширина, высота и глубина. Три.js предлагает множество готовых геометрий: сферы, цилиндры, конусы, торы и даже сложные фигуры вроде додекаэдров — для тех случаев, когда обычный куб кажется слишком банальным.

Материал (Material)

Материал определяет, как объект выглядит — его цвет, текстуру, отражательные свойства. MeshBasicMaterial — самый простой вариант, который не реагирует на освещение:

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

Цвет задается в шестнадцатеричном формате (как в CSS). Зеленый цвет 0x00ff00 стал своего рода классикой для первого примера, так как он хорошо виден на темном фоне.

Объединение в Mesh

Mesh соединяет геометрию и материал в единый объект:

const cube = new THREE.Mesh(geometry, material);

Добавление в сцену

Наконец, добавляем куб в сцену и позиционируем камеру:

scene.add(cube);

camera.position.z = 5; // Отодвигаем камеру, чтобы увидеть куб

По умолчанию все объекты создаются в точке (0,0,0). Если не отодвинуть камеру, она окажется внутри куба — что создает интересный, но бесполезный эффект полной темноты.

Полный код создания куба занимает всего несколько строк, но за этой простотой скрывается сложная математика трансформаций, проекций и растеризации, которую Три.js любезно берет на себя.

Анимация и рендеринг сцены

Статичный куб — это как фотография танца: технически правильно, но скучно. Для оживления сцены нужен цикл анимации, который будет обновлять и перерисовывать кадры.

Основа анимации в Three.js — функция requestAnimationFrame(). Она синхронизируется с частотой обновления монитора (обычно 60 FPS) и автоматически приостанавливается, когда пользователь переключается на другую вкладку — что экономит ресурсы и продлевает жизнь батареи:

function animate() {

    requestAnimationFrame(animate);

   

    // Вращаем куб по двум осям

    cube.rotation.x += 0.01;

    cube.rotation.y += 0.01;

   

    // Рендерим сцену

    renderer.render(scene, camera);

}

animate(); // Запускаем цикл
sravnenie-fps

График сравнивает стабильность FPS между requestAnimationFrame и setInterval. Видно, что requestAnimationFrame обеспечивает более плавную и согласованную анимацию.

Почему не setInterval()? Теоретически можно, но requestAnimationFrame() умнее: он знает о вертикальной синхронизации (V-Sync), не создает лишних кадров, когда вкладка неактивна, и автоматически адаптируется к производительности устройства. setInterval() работает как безжалостный метроном — тикает 60 раз в секунду, даже если браузер захлебывается от нагрузки.

Результат этого кода — гипнотически вращающийся зеленый куб. Значения 0.01 в rotation определяют скорость вращения — можете экспериментировать с этими числами, чтобы куб крутился быстрее или медленнее. Слишком большие значения могут вызвать motion sickness у особо чувствительных пользователей, а слишком маленькие — заставят их сомневаться, движется ли куб вообще.

Цикл анимации — это сердце любого интерактивного 3D-приложения. Именно здесь обновляется физика, обрабатываются пользовательские действия и происходят все изменения в сцене.

Освещение и текстуры

Зеленый куб на черном фоне — это хорошее начало, но для создания убедительных 3D-сцен нужны освещение и текстуры. Без них ваши объекты будут выглядеть как поделки из цветного картона, а не как объекты из реального мира.

Типы источников света

Три.js предлагает несколько типов освещения, каждый со своими особенностями и областями применения:

Ambient Light — окружающий свет, который равномерно освещает все объекты. Это как рассеянный дневной свет в пасмурную погоду:

const ambientLight = new THREE.AmbientLight(0x404040, 0.5);

scene.add(ambientLight);

Point Light — точечный источник света, как лампочка, которая светит во все стороны:

const pointLight = new THREE.PointLight(0xffffff, 1, 100);

pointLight.position.set(10, 10, 10);

scene.add(pointLight);

Directional Light — направленный свет, имитирующий солнце (параллельные лучи):

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);

directionalLight.position.set(5, 5, 5);

scene.add(directionalLight);

Важный нюанс: MeshBasicMaterial игнорирует освещение. Для реалистичного отображения нужно использовать MeshLambertMaterial или MeshPhongMaterial.

tipy-osveshheniya

Сравнение трёх типов освещения в Three.js: Ambient, Point и Directional. Иллюстрация помогает визуально понять, как разные источники света влияют на объекты.

Текстуры

Текстуры превращают плоские цветные поверхности в детализированные материалы. Загрузка текстуры выглядит так:

const textureLoader = new THREE.TextureLoader();

const texture = textureLoader.load('path/to/texture.jpg');

const material = new THREE.MeshLambertMaterial({ map: texture });

Текстуры можно применять не только для основного цвета, но и для bump maps (имитация рельефа), normal maps (детальная геометрия поверхности) и specular maps (управление отражением). Правда, чем больше текстур, тем медленнее загрузка — приходится балансировать между красотой и производительностью.

Комбинация правильного освещения и качественных текстур превращает примитивные геометрические фигуры в убедительные объекты, которые мозг воспринимает как «настоящие».

Импорт 3D-моделей

Создавать сложные модели из примитивных геометрий — это как собирать автомобиль из кубиков LEGO: технически возможно, но есть варианты получше. Three.js поддерживает импорт готовых 3D-моделей, созданных в специализированных программах вроде Blender, Maya или 3ds Max.

Рекомендуемый формат — GLTF (Graphics Language Transmission Format) или его бинарная версия GLB. Это как JPEG для 3D-моделей: сжато, быстро грузится и поддерживает все современные фичи — анимацию, материалы, текстуры и даже физически корректное освещение (PBR).

Для загрузки GLTF-моделей используется GLTFLoader:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();

loader.load(

    'path/to/model.gltf',

    function (gltf) {

        // Модель загружена успешно

        scene.add(gltf.scene);

    },

    function (progress) {

        // Прогресс загрузки (опционально)

        console.log('Загружено:', (progress.loaded / progress.total * 100) + '%');

    },

    function (error) {

        // Обработка ошибок

        console.error('Ошибка загрузки модели:', error);

    }

);

Загрузчик работает асинхронно — модель появится в сцене только после полной загрузки. Это важно учитывать при создании интерфейса: пользователи не любят смотреть на пустой экран, не понимая, что происходит.

GLTF-модели могут содержать анимацию — для её воспроизведения понадобится AnimationMixer. Но это уже тема для отдельной статьи, потому что анимация 3D-моделей — это кроличья нора, из которой можно не выбраться.

Импорт моделей открывает доступ к профессиональному 3D-контенту, созданному художниками, а не программистами — что обычно положительно сказывается на эстетических качествах проекта.

Использование дополнительных модулей и эффектов

Three.js — это не монолитная библиотека, а скорее экосистема с основным ядром и множеством дополнительных модулей. Многие полезные компоненты живут в папке examples/jsm/ — это как расширения для браузера, только для 3D-сцен.

OrbitControls — самый популярный дополнительный модуль, который добавляет интерактивное управление камерой. Пользователи могут вращать, приближать и панорамировать сцену мышью или тачпадом:

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);

controls.enableDamping = true; // Плавное затухание движения

controls.dampingFactor = 0.05;

Другие полезные модули включают различные загрузчики для специфических форматов (OBJLoader, FBXLoader), эффекты постобработки (bloom, depth of field, color correction), физические симуляции и многое другое. Правда, чем больше модулей подключаете, тем тяжелее становится ваш бандл — а пользователи не любят ждать.

Важное правило: все дополнительные модули должны быть из той же версии Three.js, что и основная библиотека. Смешивание версий — верный путь к загадочным ошибкам, которые будут преследовать вас в 3 часа ночи перед дедлайном.

Дополнительные модули расширяют возможности Three.js от базового 3D-рендеринга до полноценных интерактивных приложений с продвинутой графикой и пользовательским интерфейсом.

Запуск на локальном сервере

Веб-разработка была бы слишком простой, если бы все работало просто при открытии HTML-файла в браузере. Из-за политики безопасности браузеров (CORS — Cross-Origin Resource Sharing) загрузка внешних файлов из локальной файловой системы заблокирована. Это означает, что ваши красивые текстуры и 3D-модели останутся недоступными.

Когда можно работать без сервера

Если вы используете только процедурные геометрии и встроенные материалы без внешних текстур — можете открывать HTML прямо из проводника. Но как только понадобится загрузить изображение, модель или любой внешний ресурс — добро пожаловать в мир локальных серверов.

Варианты серверов

Live Server (VS Code) — самый простой вариант для пользователей Visual Studio Code. Устанавливается как расширение, запускается одним кликом.

Five Server — современная альтернатива с горячей перезагрузкой:

npm -g i five-server

five-server . -p 8000

Servez — простое десктопное приложение с графическим интерфейсом для тех, кто боится командной строки.

http-server (Node.js) — минималистичный HTTP-сервер:

npm install http-server -g

http-server . -p 8000

Python — если у вас установлен Python (а он есть на большинстве систем):

# Python 3.x

python -m http.server 8000

Ruby (WEBrick) — для любителей Ruby:

ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"

PHP — встроенный сервер с версии 5.4:

php -S localhost:8000

Lighttpd — полноценный веб-сервер для серьезных проектов.

IIS — для пользователей Windows Server с настройкой MIME-типов для .fbx и .obj файлов.

Выбор сервера — дело вкуса и экосистемы проекта. Главное — чтобы он умел отдавать статические файлы и поддерживал CORS.

Пример проекта с Three.js

Теория без практики — как рецепт без ингредиентов: звучит заманчиво, но попробовать нельзя. Давайте объединим все изученные компоненты в работающий пример, который можно потрогать, покрутить и показать друзьям (или заказчику).

Полный код создает интерактивную сцену с освещенным кубом, который можно вращать мышью:

<!DOCTYPE html>

<html>

<head>

<meta charset=»utf-8″>

<title>Three.js Interactive Cube</title>

<style>

body { margin: 0; overflow: hidden; }

canvas { display: block; }

</style>

</head>

<body>

<script type=»module»>

import * as THREE from ‘https://unpkg.com/three@0.150.0/build/three.module.js’;

import { OrbitControls } from ‘https://unpkg.com/three@0.150.0/examples/jsm/controls/OrbitControls.js’;

// Создание сцены, камеры и рендерера

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);

renderer.shadowMap.enabled = true;

document.body.appendChild(renderer.domElement);

// Освещение

const ambientLight = new THREE.AmbientLight(0x404040, 0.6);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);

directionalLight.position.set(10, 10, 5);

scene.add(ambientLight, directionalLight);

// Создание куба с реалистичным материалом

const geometry = new THREE.BoxGeometry();

const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });

const cube = new THREE.Mesh(geometry, material);

scene.add(cube);

// Интерактивное управление

const controls = new OrbitControls(camera, renderer.domElement);

camera.position.z = 5;

// Анимация

function animate() {

requestAnimationFrame(animate);

cube.rotation.x += 0.005;

cube.rotation.y += 0.005;

controls.update();

renderer.render(scene, camera);

}

animate();

</script>

</body>

</html>

Результат — вращающийся зеленый куб с реалистичным освещением, который можно крутить и приближать мышью. Простой, но демонстрирующий основные принципы Three.js.

Живой пример доступен на  CodePen — можете экспериментировать с параметрами прямо в браузере, не настраивая локальную среду разработки.

Заключение

Путь от «что такое Three.js?» до вращающегося 3D-куба с интерактивным управлением занимает удивительно мало времени — особенно если сравнивать с изучением «сырого» WebGL, где аналогичный результат потребовал бы недель изучения и сотен строк кода. Подведем итоги:

  • Three.js — инструмент для работы с 3D-графикой. Он делает WebGL доступнее для разработчиков.
  • Библиотека упрощает процесс создания 3D-сцен. Большая часть сложной математики скрыта за готовыми методами.
  • Three.js поддерживает анимации и текстуры. Можно создавать реалистичное освещение и импортировать модели.
  • С помощью библиотеки легко начать. Достаточно установить её и подключить несколько базовых компонентов.
  • Three.js востребован в индустрии. Его используют NASA, Google, Apple и другие компании.

Рекомендуем обратить внимание на подборку курсов по 3D-моделированию. Если вы только начинаете осваивать профессию, курсы помогут быстро погрузиться в основы Three.js. Вы получите теорию и практику для создания собственных визуализаций и эффектов.

Читайте также
Категории курсов