Использование библиотеки three.js для построения 3D-сцен
Three.js – это библиотека JavaScript, содержащая набор готовых классов для создания и отображения интерактивной 3D графики в WebGL. В свою очередь, WebGL – это программная библиотека для JavaScript, которая позволяет создавать 3D графику, функционирующую в браузерах. Данная библиотека основана на архитектуре библиотеки OpenGL. WebGL использует язык программирования шейдеров GLSL, который имеет Си-подобный синтаксис. WebGL позволяет строить изображения непосредственно в браузере и для этого использует объект canvas.
Однако программирование шейдеров это довольно трудоемкий процесс. Необходимо понимать механизм работы шейдеров, описывать каждую точку, линию, грань, нормаль и т.д., использовать язык программирования, отличимый от JavaScript.
Библиотека Three.js значительно упрощает работу. При использовании Three.js отпадает необходимость в написании шейдеров и появляется возможность оперировать объектами, свойственными для JavaScript. (Скачать минимизированную версию three.js)
Главным идеологом и разработчиком библиотеки является Ricardo Cobello, известный под творческим псевдонимом Mr.Doob. В то же время, в ее разработке принимают участие большое число программистов, поскольку библиотека представляет собой открытый проект.
Основными ключевыми понятиями в Three.js являются:
Scene (Сцена) – область в которой размещаются все объекты;
Camera (Камера) – направление визуализации сцены, т.е. место откуда мы наблюдаем сцену;
Renderer (Визуализация) – расчет и проецирование сцены на экран.
Объекты добавляются на сцену, а затем рендерер "фотографирует" сцену с позиции камеры.
Пространство для отрисовки (сцена)
Сцена (scene) это место, где все происходит. Когда создаются новые объекты, они добавляются в сцену, чтобы их можно было увидеть. В three.js роль сцены выполняет объект Scene. Сцену создает следующий код:
var scene = new THREE.Scene();
В дальнейшем для добавления объектов на сцену будет использоваться метод
scene.add().
Проекция сцены на экран (камера)
Камера в Three.js – это объект, который определяет, с какой точки и как мы видим сцену. Без камеры рендерер ничего не покажет. Все камеры наследуются от базового класса THREE.Camera, но чаще всего используются два типа: PerspectiveCamera и OrthographicCamera.

PerspectiveCamera – перспективная камера (самая популярная). Это камера, имитирующая человеческий глаз: объекты ближе – крупнее, дальше – мельче.
Создаётся так:
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
где параметры определяют:
- fov (Field of View – угол обзора по вертикали, в градусах). Обычно 45–75. Больший fov – шире видно, как рыбий глаз; меньший – как телескоп.
- aspect (соотношение сторон). Часто соотношение сторон задают, как window.innerWidth / window.innerHeight.
- near (ближняя плоскость отсечения). Объекты ближе этого значения не отрисовываются. Обычно 0.1–1.
- far (дальняя плоскость отсечения). Объекты дальше – не видно. Обычно 1000–10000. Слишком большой far может вызвать проблемы с точностью (z-fighting).
OrthographicCamera – ортографическая камера (параллельная проекция). Объекты одинакового размера выглядят одинаково независимо от расстояния. Полезна для 2D-игр, изометрии, CAD, схем.
Создаётся так:
const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
где параметры определяют прямоугольный объём видимости
Основные свойства камеры (общие для всех типов)
- position – позиция камеры в мире (Vector3). Например, camera.position.set(0, 5, 10);.
- rotation – поворот камеры (Euler angles).
- lookAt(vector3) – удобный метод, чтобы камера смотрела на точку: camera.lookAt(0, 0, 0);.
- up – вектор "вверх" (по умолчанию new THREE.Vector3(0, 1, 0) – ось Y). Меняет, что считается верхом (полезно для полётов или необычных ориентаций).
Освещение сцены
Three.js предлагает несколько типов источников света. Вот самые часто используемые:

AmbientLight – равномерный фоновый свет со всех направлений. Не создаёт теней, просто "подсвечивает" всё одинаково. Полезен, чтобы избежать полностью чёрных теней.
const ambient = new THREE.AmbientLight(0xffffff, 0.5); // цвет, интенсивность scene.add(ambient);
DirectionalLight – направленный свет, как солнце. Лучи параллельные, идут из бесконечности в заданном направлении. Отлично создаёт резкие тени.javascript
const directional = new THREE.DirectionalLight(0xffffff, 1); directional.position.set(5, 10, 7); // направление определяется позицией scene.add(directional);
PointLight – точечный свет, как лампочка. Излучает во все стороны, интенсивность падает с расстоянием (attenuation).
const point = new THREE.PointLight(0xff0000, 2, 100); // цвет, интенсивность, расстояние point.position.set(0, 5, 0); scene.add(point);
Можно добавить несколько с разными цветами для интересных эффектов.
SpotLight – имитирует прожектор или фонарик: свет идёт из точки в определённом направлении в форме конуса, с возможностью мягких краёв и теней. SpotLight сочетает свойства PointLight (свет из точки, затухание с расстоянием) и DirectionalLight (направление).
const spotLight = new THREE.SpotLight( 0xffffff, // цвет 2, // интенсивность (intensity) 50, // расстояние (distance) – до какого расстояния свет доходит (0 = бесконечно) Math.PI / 6, // угол конуса в радианах (angle) – ширина луча 0.1, // penumbra – мягкость краёв (0–1, где 1 = очень мягкие) 2 // decay – как быстро затухает интенсивность с расстоянием (1 = реалистично, 2 = физически точно) ); spotLight.position.set(5, 10, 5); // позиция прожектора spotLight.target.position.set(0, 0, 0); // куда направлен (можно любой объект) scene.add(spotLight); scene.add(spotLight.target); // важно добавить target в сцену!
Ключевые параметры:
- angle – максимальный угол конуса (в радианах). Обычно Math.PI / 4 (45°) до Math.PI / 8 (22.5°) для узкого луча. Чем меньше – тем уже луч.
- penumbra – насколько мягкие края конуса (0 = резкие, 1 = полностью размытые).
- decay – затухание. В старых версиях было 1 по умолчанию, теперь часто 2 для физической точности.
Размещение и визуализация объектов на сцене
Все объекты, которые будут добавлены на сцену, представляют собой сетку полигонов (см. полигональное моделирование). Для их представления и инициализации создан специальный класс:
Mesh (сетка) – это объект, который сочетает в себе форму (Geometry) и внешний вид (Material). Простыми словами: Mesh = Geometry + Material. Все видимые объекты в Three.js (кубы, сферы, модели и т.д.) – это экземпляры класса THREE.Mesh.
const geometry = new THREE.BoxGeometry(2, 2, 2); // форма: куб const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); // материал: зелёный, реагирует на свет const mesh = new THREE.Mesh(geometry, material); // создаём Mesh scene.add(mesh); // добавляем на сцену
Geometry – форма объекта
Geometry определяет вершины (vertices), грани (faces) и нормали (для освещения). Three.js имеет много встроенных геометрий:
- BoxGeometry – куб
- SphereGeometry – сфера
- PlaneGeometry – плоскость
- TorusGeometry – тор (бублик)
- CylinderGeometry – цилиндр
и многие другие.
Material – внешний вид
Material определяет, как поверхность реагирует на свет, цвет, текстуры и т.д.
- MeshStandardMaterial – физически корректный материал (PBR).
- MeshBasicMaterial – простой цвет, не реагирует на свет (полезно для UI или glowing-объектов).
- MeshPhongMaterial – старый, с бликами.
- MeshLambertMaterial – матовый, без бликов.
- MeshPhysicalMaterial – расширенный Standard с дополнительными эффектами (clearcoat, transmission).
Для получения построенной сцены на экране необходимо вызвать метод render у класса renderer = new THREE.WebGLRenderer();
var renderer = new THREE.WebGLRenderer(); renderer.render( scene, camera );
Пример кода, демонстрирующий вращение шара вокруг куба в начале статьи:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Use Three.js</title> <script src="https://cgraph.ru/files/lib/three.min.js"></script> </head> <body> <div width=800 height=600 id="draw"></div>
<script>
// ==================== СЦЕНА ====================
// Создаём сцену — основной контейнер для всех объектов, света и камеры
var scene = new THREE.Scene();
// ==================== КАМЕРА ====================
// Создаём перспективную камеру
// Параметры: угол обзора (75°), соотношение сторон (800x600), ближняя плоскость (0.1), дальняя (1000)
var camera = new THREE.PerspectiveCamera(75, 800 / 600, 0.1, 1000);
// ==================== РЕНДЕРЕР ====================
// Создаём WebGL-рендерер для отрисовки сцены
var renderer = new THREE.WebGLRenderer();
// Устанавливаем фиксированный размер canvas (800x600 пикселей)
renderer.setSize(800, 600);
// Находим контейнер на странице с id="draw" и добавляем в него canvas рендерера
var mContainer = document.getElementById('draw');
mContainer.appendChild(renderer.domElement);
// ==================== ОСВЕЩЕНИЕ ====================
// Передний прожектор (SpotLight) — мягкий белый свет
var frontSpot = new THREE.SpotLight(0xeeeece); // Цвет света — теплый белый
frontSpot.position.set(100, 100, 100); // Позиция прожектора в пространстве
scene.add(frontSpot); // Добавляем свет на сцену
// Задний прожектор — освещает с противоположной стороны для объёмности
var backSpot = new THREE.SpotLight(0xeeeece);
backSpot.position.set(-100, -100, -100);
scene.add(backSpot);
// ==================== КУБ ====================
// Геометрия куба размером 10×10×10
var geometry = new THREE.BoxGeometry(10, 10, 10);
// Материал MeshBasicMaterial — простой цвет, НЕ реагирует на свет (поэтому свет на кубе не влияет)
var material = new THREE.MeshBasicMaterial({
color: 0xdd55ff, // Фиолетово-розовый цвет
});
// Создаём меш (видимый объект) из геометрии и материала
var cube = new THREE.Mesh(geometry, material);
// Добавляем куб на сцену
scene.add(cube);
// ==================== СФЕРА ====================
// Геометрия сферы: радиус 5, 20 сегментов по ширине, 20 по высоте (чем больше — тем глаже)
var geometry = new THREE.SphereGeometry(5, 20, 20);
// Материал MeshPhongMaterial — реагирует на свет, имеет блики (specular)
var material = new THREE.MeshPhongMaterial({
color: 0xdaa520, // Золотисто-оранжевый цвет
specular: 0x333333, // Цвет блика (тёмно-серый)
shininess: 30 // По умолчанию 30, можно изменить степень блеска
});
// Создаём сферу
var sphere = new THREE.Mesh(geometry, material);
// Смещаем сферу вправо по оси X
sphere.position.x = 15;
// Добавляем сферу на сцену
scene.add(sphere);
// ==================== НАСТРОЙКИ КАМЕРЫ И АНИМАЦИИ ====================
var angle = 0; // Угол для анимации движения сферы по кругу
// Отодвигаем камеру по оси Z, чтобы видеть оба объекта
camera.position.z = 25;
// ==================== ЦИКЛ АНИМАЦИИ ====================
function render() {
// Запрашиваем следующий кадр у браузера (обычно ~60 FPS)
requestAnimationFrame(render);
// Вращаем куб по двум осям для постоянного движения
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// Двигаем сферу по кругу в плоскости XZ (радиус 10, центр в x=15, z=0)
sphere.position.z = 10 * Math.sin(angle);
sphere.position.x = 15 + 10 * Math.cos(angle); // Добавляем 15, чтобы центр круга был смещён
angle += 0.01; // Увеличиваем угол для следующего кадра
// Отрисовываем сцену с текущей позиции камеры
renderer.render(scene, camera);
}
// Запускаем анимацию
render();
</script>