Структура типичного Three.js-приложения

Three.js строится вокруг трёх ключевых компонентов: сцены, камеры и рендера. Каждое приложение начинается с создания этих объектов, которые формируют каркас 3D-пространства.

  • Сцена (THREE.Scene) — контейнер для всех объектов, освещения и эффектов. В неё добавляются меши, линии, группы объектов, а также фон и туман.
  • Камера (THREE.Camera) — точка зрения, с которой пользователь видит сцену. Чаще всего используется THREE.PerspectiveCamera, обеспечивающая перспективное отображение, однако для 2D или изометрии подходит THREE.OrthographicCamera.
  • Рендер (THREE.WebGLRenderer) — объект, который превращает сцену и камеру в пиксели на экране. Важные параметры: размер рендеринга (setSize) и цвет фона (setClearColor).

Инициализация сцены и рендера

Создание сцены и рендера обычно происходит в начале скрипта:

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

Камеру обычно позиционируют в пространстве, чтобы она могла видеть все объекты сцены:

camera.position.set(0, 2, 5);
camera.lookAt(0, 0, 0);

Основные типы объектов

Объекты в Three.js делятся на несколько категорий:

  • Геометрия (THREE.Geometry или THREE.BufferGeometry) — набор вершин, ребер и граней, описывающих форму. BufferGeometry предпочтительнее для производительности.
  • Материалы (THREE.Material) — определяют, как объект будет отображаться: цвет, текстура, отражение. Наиболее используемые материалы: MeshBasicMaterial, MeshStandardMaterial и MeshPhongMaterial.
  • Меши (THREE.Mesh) — комбинация геометрии и материала, создающая видимый объект.

Пример создания меша:

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

Освещение

Для реалистичного отображения объектов необходимы источники света. В Three.js доступны несколько типов:

  • AmbientLight — равномерное освещение сцены, не создающее теней.
  • DirectionalLight — имитирует солнце, создаёт параллельные лучи и тени.
  • PointLight — точечный источник света, распространяющийся во все стороны.
  • SpotLight — направленный конус света, подходит для сцен с локальным освещением.

Пример добавления света:

const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7.5);
scene.add(light);

Анимация и рендер-цикл

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

function animate() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  renderer.render(scene, camera);
}

animate();

requestAnimationFrame обеспечивает плавность обновления и синхронизацию с частотой обновления экрана.

Обработка событий и интерактивность

Для взаимодействия с пользователем добавляются обработчики событий, чаще всего на изменение размеров окна или на действия мыши:

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

Для управления камерой используют контроллеры, например, OrbitControls, позволяющий вращать камеру вокруг центра сцены:

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

Организация сцены и оптимизация

Для крупных проектов объекты группируют с помощью THREE.Group, чтобы упростить трансформации:

const group = new THREE.Group();
group.add(cube);
scene.add(group);
group.rotation.y = Math.PI / 4;

Производительность зависит от количества вершин, материалов и источников света. Для оптимизации применяют:

  • InstancedMesh для множества одинаковых объектов.
  • LOD (Level of Detail) для уменьшения геометрии с увеличением расстояния.
  • Бэкинг света и текстур для снижения нагрузки на рендеринг в реальном времени.

Загрузка ресурсов

Three.js предоставляет классы загрузчиков для текстур, моделей и шейдеров:

const textureLoader = new THREE.TextureLoader();
textureLoader.load('texture.jpg', (texture) => {
  material.map = texture;
  material.needsUpdate = true;
});

Для моделей используют GLTFLoader, OBJLoader и другие:

const loader = new THREE.GLTFLoader();
loader.load('model.gltf', (gltf) => {
  scene.add(gltf.scene);
});

Постобработка и эффекты

Three.js поддерживает постобработку с использованием EffectComposer и шейдерных эффектов:

  • Bloom — имитация свечения ярких объектов.
  • Depth of Field — размытие объектов вне фокуса.
  • FilmPass — эффект кинопленки.

Эффекты применяются после основного рендера и позволяют создавать профессиональные визуальные решения.

Структурная схема типичного приложения

  1. Импорт библиотеки и модулей (грузчики, контроллеры).
  2. Инициализация сцены, камеры и рендерера.
  3. Создание объектов и материалов.
  4. Настройка источников света.
  5. Добавление контроллеров и обработчиков событий.
  6. Настройка анимации и рендер-цикла.
  7. Загрузка ресурсов (текстур, моделей).
  8. Применение постобработки и визуальных эффектов.
  9. Оптимизация производительности (LOD, InstancedMesh).

Эта структура обеспечивает гибкость и масштабируемость приложений, позволяя строить как простые визуализации, так и сложные интерактивные 3D-миры.