Создание 3D сцен с помощью библиотеки Three.js
Библиотека three.js предоставляет инструменты для создания трехмерной графики в браузере. С её помощью можно строить сцены, анимировать объекты, загружать модели и многое другое. Далее рассмотрены основные приёмы работы.
Базовое создание сцены с объектом
Каким образом можно отобразить вращающийся 3D объект на веб-странице?
Цель:
Показать минимальный код для отображения вращающегося куба с эффектом перспективы.
// Подключаем three.js через CDN или модуль
import * as THREE from 'three';
// Сцена, камера, рендерер
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.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Освещение
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);
// Анимация
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();Three js (three.js)
В браузере появится зелёный куб, медленно вращающийся вокруг осей X и Y.
Возможные проблемы:
- Куб не отображается – проверьте, что камера направлена на объект и не находится внутри него.
- Ошибки CORS при загрузке из CDN – используйте локальный сервер или явно укажите версию.
- Тёмный экран – добавлено ли освещение? MeshStandardMaterial требует источников света.
Случаи использования:
Этот шаблон подходит для любых прототипов 3D сцен: от простых демонстраций до интерактивных витрин.
Варианты настройки сцены
Какой тип камеры выбрать для сцены?
Цель:
Сравнить перспективную и ортографическую камеры для разных задач.
// Перспективная камера (PerspectiveCamera)
const perspCamera = new THREE.PerspectiveCamera(
75, // поле обзора в градусах
window.innerWidth / window.innerHeight, // соотношение сторон
0.1, // ближняя плоскость отсечения
1000 // дальняя плоскость отсечения
);
// Ортографическая камера (OrthographicCamera)
const aspect = window.innerWidth / window.innerHeight;
const orthoCamera = new THREE.OrthographicCamera(
-1 * aspect, 1 * aspect, // левая, правая границы
1, -1, // верхняя, нижняя границы
0.1, 1000 // ближняя, дальняя плоскости
);Перспективная камера создаёт иллюзию глубины, ортографическая сохраняет реальные размеры объекта независимо от расстояния.
Типичные ошибки:
- Неправильные значения near/far – если задать слишком маленький near (<0.01), могут возникнуть артефакты z-борьбы. Слишком большой near отсечёт объект.
- Для ортографической камеры часто забывают пересчитать границы при изменении размеров окна.
Случаи использования:
Перспективная – для виртуальных туров, игр, архитектурной визуализации. Ортографическая – для изометрических игр, 2D интерфейсов с 3D элементами.
Как добавить освещение и тени в three.js?
Цель:
Настроить источники света и отбрасывание теней для реалистичности.
// Включаем рендеринг теней
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Направленный свет с тенями
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(2, 3, 4);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
scene.add(directionalLight);
// Вспомогательная плоскость для приёма теней
const planeGeometry = new THREE.PlaneGeometry(5, 5);
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xeeeeee });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
plane.position.y = -1;
plane.receiveShadow = true;
scene.add(plane);
// Куб отбрасывает тень
cube.castShadow = true;Куб отбрасывает тень на плоскость, создавая ощущение пространства.
Проблемы:
- Тени не видны – проверьте, что у объектов установлены castShadow/receiveShadow, что источник света castShadow = true, и что включён shadowMap у рендерера.
- Тени низкого качества – увеличьте shadow.mapSize.width/height.
- Свет не попадает на объект – проверьте дальность тени (shadow.camera.near/far).
Случаи использования:
Любая сцена, где важна визуальная глубина: игры, 3D редакторы, симуляторы.
Как загрузить и отобразить готовую 3D модель?
Цель:
Показать загрузку модели в формате glTF с помощью GLTFLoader.
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load(
'path/to/model.glb',
function (gltf) {
scene.add(gltf.scene);
// Настроить масштаб, позицию при необходимости
gltf.scene.position.set(0, 0, 0);
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% загружено');
},
function (error) {
console.error('Ошибка загрузки модели', error);
}
);После загрузки модель появляется в сцене. Прогресс отображается в консоли.
Типичные ошибки:
- CORS – если файл лежит на другом домене, сервер должен отдавать заголовки CORS. Решение – разместить модель локально или настроить сервер.
- Модель не видна – проверьте, что она не слишком мала или не находится внутри стены. Часто помогает сбросить позицию и масштаб.
- Отсутствие текстур – многие glTF содержат внешние текстуры, их пути должны быть корректны относительно файла модели.
Случаи использования:
Презентации продуктов, виртуальные примерочные, демонстрация архитектурных проектов.
Расширенные примеры использования three.js
Управление камерой с помощью OrbitControls
Описание:
Добавление интерактивного управления вращением и масштабированием сцены.
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // плавное движение
controls.dampingFactor = 0.05;
controls.screenSpacePanning = true;
function animate() {
requestAnimationFrame(animate);
controls.update(); // необходимо для damping
renderer.render(scene, camera);
}
animate();Теперь пользователь может вращать сцену мышью, приближать и отдалять колесом. Damping добавляет инерцию.
Система частиц (Points)
Описание:
Создание анимированного облака из 5000 частиц.
const particleCount = 5000;
const positions = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount * 3; i += 3) {
positions[i] = (Math.random() - 0.5) * 20;
positions[i+1] = (Math.random() - 0.5) * 20;
positions[i+2] = (Math.random() - 0.5) * 20;
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({
color: 0x88aaff,
size: 0.1,
transparent: true,
opacity: 0.8
});
const particles = new THREE.Points(geometry, material);
scene.add(particles);
// Анимация вращения
function animateParticles() {
requestAnimationFrame(animateParticles);
particles.rotation.y += 0.001;
renderer.render(scene, camera);
}
animateParticles();На экране медленно вращается звёздное поле из голубых точек.
Вариации:
Можно задать текстуру частицы через material.map, использовать PointsMaterial для имитации дыма, огня.
Простой шейдер с uniform time
Описание:
Написание собственного Material с ShaderMaterial и анимацией цвета во времени.
const vertexShader = `
varying vec3 vPosition;
void main() {
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShader = `
uniform float uTime;
varying vec3 vPosition;
void main() {
vec3 color = 0.5 + 0.5 * cos(uTime + vPosition.xyz * 2.0);
gl_FragColor = vec4(color, 1.0);
}
`;
const material = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 }
},
vertexShader: vertexShader,
fragmentShader: fragmentShader
});
const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), material);
scene.add(sphere);
// Обновление времени в анимации
function animateShader() {
requestAnimationFrame(animateShader);
material.uniforms.uTime.value += 0.01;
renderer.render(scene, camera);
}
animateShader();Сфера переливается радужными цветами, изменяющимися со временем.
Примечание:
Шейдеры позволяют создавать уникальные эффекты, не достижимые стандартными материалами.