Three.js и WebGL: полный обзор 3D на сайтах

Что такое WebGL и Three.js, когда 3D на сайте окупается, а когда только добавляет вес: 8 сфер, плюсы и минусы, сравнение с Babylon.js, Spline и видео, правила скорости, WebGPU и примеры кода.

Стек и технологии Обновлено

Коротко

WebGL — это доступ браузера к видеокарте, а Three.js — самая популярная бесплатная библиотека поверх него: она превращает низкоуровневые графические команды в сцену с камерой, светом, материалами и моделями. Вместе они дают настоящий 3D на странице без плагинов — просмотр и конфигураторы товаров, эффектные первые экраны, визуализацию данных, игры и AR. Новый стандарт WebGPU Three.js тоже поддерживает, а браузерная поддержка WebGPU растёт. Цена 3D — вес и батарея: модели нужно сжимать, сцены останавливать вне экрана, а слабым устройствам и тем, кто отключил движение, показывать облегчённую версию.

Three.js и WebGL коротко: паспорт

Главные факты о стандарте и библиотеке одной таблицей.

WebGL
Стандарт Khronos Group: доступ браузера к видеокарте; WebGL 2 поддерживается везде
WebGPU
Новое поколение: ближе к современным графическим API, с вычислениями на видеокарте; поддержка растёт
Three.js
3D-библиотека Рикардо Кабельо (mrdoob), 2010 год; лицензия MIT
Что даёт
Сцены, камеры, свет, физически корректные материалы, загрузчики моделей, постобработка
Рендереры
WebGLRenderer и WebGPURenderer с автоматическим откатом на WebGL
Формат моделей
glTF — «JPEG для 3D»; сжатие Draco или Meshopt, текстуры в KTX2
Релизы
Примерно раз в месяц, нумеруются ревизиями (r186 на момент написания)
С React
React Three Fiber и drei — сцены как компоненты
Альтернативы
Babylon.js, PlayCanvas; для сцен без кода — Spline
Модели делают в
Blender и других 3D-редакторах, затем экспортируют в glTF

Для чего применяют Three.js: 8 сфер

3D окупает свой вес там, где показывает то, чего не покажет картинка.

  1. 01

    Товар в 3D

    Вращать, приближать и смотреть со всех сторон — до покупки.

    glTFOrbitControls

  2. 02

    Конфигураторы

    Цвет, материал, размер — модель меняется в реальном времени.

    мебельавто

  3. 03

    Эффектные первые экраны

    Запуски и премиальные бренды, которые должны запомниться.

    шейдерыпрокрутка

  4. 04

    Визуализация данных

    Тысячи точек, глобусы и сети, которые не помещаются в 2D.

    InstancedMesh

  5. 05

    Недвижимость и интерьеры

    Прогулка по квартире или офису до того, как их построили.

    туры

  6. 06

    Игры и промо

    Небольшие игры в браузере без установки.

    физика

  7. 07

    AR и VR

    WebXR ставит модель в комнату через камеру телефона.

    WebXR

  8. 08

    Интерфейсы с глубиной

    Лёгкие 3D-акценты в интерфейсе там, где они помогают понять.

    React Three Fiber

Плюсы и минусы Three.js

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

Плюсы · 8

  • Настоящий 3D без плагинов

    Работает во всех современных браузерах на телефонах и компьютерах.

  • Удобный уровень абстракции

    Сцена, камера и объект вместо сотен строк низкоуровневого графического кода.

  • Огромное сообщество

    Тысячи примеров, ответов и готовых эффектов.

  • glTF и хорошие загрузчики

    Модели из Blender приходят с материалами и анимациями.

  • Физически корректные материалы

    Металл, дерево и стекло выглядят правдоподобно при любом свете.

  • Готов к WebGPU

    Одна и та же сцена может рисоваться через WebGPU и откатываться на WebGL.

  • Работает с React

    React Three Fiber превращает сцены в компоненты.

  • Бесплатный

    Лицензия MIT, без отчислений за коммерческое использование.

Минусы · 8

  • Вес

    Библиотека плюс модели и текстуры — мегабайты, если не сжимать.

  • Батарея и нагрев

    Сцена, которая рисуется 60 раз в секунду, постоянно нагружает видеокарту.

  • Слабые устройства

    Старые телефоны дёргаются на тяжёлых эффектах — нужна облегчённая версия.

  • Невидимо для поиска

    Нарисованное на холсте — не текст: содержание должно быть и в HTML.

  • Часто меняющийся API

    Ежемесячные релизы иногда переименовывают и убирают части — обновления требуют внимания.

  • Нужны навыки 3D

    Хорошим сценам нужны моделирование, свет и шейдеры, а не только код.

  • Доступность

    Программы чтения с экрана не видят холст; управление с клавиатуры пишется вручную.

  • Не игровой движок

    Физика, редактор и игровая логика приходят из других инструментов.

Three.js и другие: сравнение с Babylon.js, PlayCanvas, Spline и видео

Способы показать 3D на странице — от кода до заранее отрисованного ролика.

КритерийThree.jsBabylon.jsPlayCanvasSplineВидео
Что это 3D-библиотека 3D-движок движок с редактором инструмент дизайнера заранее отрисованный ролик
Интерактив полный полный полный базовый нет
Гибкость самая высокая высокая высокая в рамках инструмента нет
Вес средний больше средний средний зависит от файла
Кто делает разработчик разработчик разработчик с редактором дизайнер 3D-художник
Лучше всего для своих сцен и просмотра товаров сложных 3D-приложений и игр браузерных игр и рекламы быстрого декоративного 3D сложных сцен без взаимодействия

Когда 3D на Three.js оправдан, а когда нет

Десять типичных задач с вердиктом.

  • Товар со всех сторон

    Лучший выбор

    3D показывает то, чего не покажут фото.

  • Конфигуратор

    Лучший выбор

    Сочетания меняются в реальном времени вместо сотен рендеров.

  • Запуск премиального бренда

    Лучший выбор

    Запоминающийся первый экран стоит своего веса.

  • Визуализация больших данных

    Лучший выбор

    Тысячи объектов рисует видеокарта.

  • Декоративный фон

    Подходит

    Часто видео или CSS дают тот же эффект легче.

  • Сложная сцена без взаимодействия

    Подходит

    Сжатое видео может быть дешевле для устройства.

  • Полноценная игра

    Подходит

    Возможно, но движок вроде Babylon.js или PlayCanvas даёт больше из коробки.

  • Корпоративный сайт «чтобы было современно»

    Другой язык

    3D без задачи добавляет вес и отвлекает.

  • Аудитория на слабых телефонах

    Другой язык

    Фото и немного движения работают лучше.

  • Содержание, которое должны найти в поиске

    Другой язык

    Тексту место в HTML, а не на холсте.

Как сделать 3D быстрым: 8 правил

  1. 01

    Сжимать модели

    Draco или Meshopt уменьшают glTF в несколько раз.

  2. 02

    Текстуры в KTX2

    Они остаются сжатыми даже в памяти видеокарты.

  3. 03

    Ограничить плотность пикселей

    Выше 2x глаз разницы не видит, а видеокарта рисует вдвое больше.

  4. 04

    Рисовать, только когда видно

    Сцена за пределами экрана останавливается — батарея говорит спасибо.

  5. 05

    Грузить по требованию

    Библиотека и модель загружаются, когда посетитель доходит до блока.

  6. 06

    Меньше вызовов отрисовки

    Тысячи одинаковых объектов рисуются как один через InstancedMesh.

  7. 07

    Сначала картинка

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

  8. 08

    Учитывать «уменьшить движение»

    Если в системе отключено движение, показывать один неподвижный кадр.

Экосистема Three.js: инструменты для частых задач

Библиотека рисует, а модели, сжатие и эффекты приходят вокруг неё.

ЗадачаИнструменты
Моделирование Blender
Сжатие glTF gltf-transform, Draco, Meshopt
Текстуры KTX2, Basis Universal
Сцены в React React Three Fiber, drei
Постобработка postprocessing, EffectComposer
Физика Rapier, cannon-es
Таймлайн анимации Theatre.js
Отладка lil-gui, Spector.js
AR и VR WebXR

Частые ошибки с 3D на сайтах

  1. Модель прямо из редактора

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

  2. Бесконечная отрисовка

    Сцена, которая рисуется, даже когда её никто не видит, впустую греет телефон.

  3. Текст внутри сцены

    Его не видят ни поисковики, ни программы чтения с экрана.

  4. Нет запасного варианта

    Если WebGL не запустился, посетитель видит пустой прямоугольник.

  5. Забытые ресурсы

    Геометрии и текстуры, которые не освободили, съедают память видеокарты при каждой смене страницы.

  6. 3D ради 3D

    Если сцена не объясняет и не продаёт, она только добавляет вес.

Как выглядит Three.js: 3 примера

Минимальная сцена, просмотр товара и отрисовка только на виду. Проверены TypeScript 7 с Three.js r186; первый и третий запущены в Chromium.

Минимальная сцена

Вращающийся куб со светом, правильный размер при изменении окна и ограниченная плотность пикселей.

scene.ts
import * as THREE from 'three';

// сцена, камера и рендерер — три вещи, с которых начинается любая 3D-страница
const canvas = document.querySelector<HTMLCanvasElement>('#scene')!;
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // выше 2x глаз разницы не видит, а видеокарта — видит

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
camera.position.set(0, 1.2, 4);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0xe4ff4e, roughness: 0.4 }),
);
scene.add(cube, new THREE.HemisphereLight(0xffffff, 0x222222, 2.5));

function resize() {
  const { clientWidth: w, clientHeight: h } = canvas;
  renderer.setSize(w, h, false);
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
}
window.addEventListener('resize', resize);
resize();

renderer.setAnimationLoop((time) => {
  cube.rotation.y = time / 1000;
  renderer.render(scene, camera);
});

Просмотр товара

Сжатая модель glTF, которую посетитель вращает и приближает в заданных пределах.

product.ts
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// просмотр товара: сжатая модель glTF, которую посетитель вращает и приближает
export async function showProduct(canvas: HTMLCanvasElement, url: string) {
  const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);

  const scene = new THREE.Scene();
  scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 3));
  const camera = new THREE.PerspectiveCamera(35, canvas.clientWidth / canvas.clientHeight, 0.1, 50);
  camera.position.set(0, 0.6, 2.4);

  const draco = new DRACOLoader().setDecoderPath('/draco/'); // модель сжата в несколько раз
  const gltf = await new GLTFLoader().setDRACOLoader(draco).loadAsync(url);
  scene.add(gltf.scene);

  const controls = new OrbitControls(camera, canvas);
  controls.enableDamping = true;
  controls.minDistance = 1;
  controls.maxDistance = 4;

  renderer.setAnimationLoop(() => {
    controls.update();
    renderer.render(scene, camera);
  });
  return renderer;
}

Рисовать, только пока видно

За пределами экрана сцена останавливается; при отключённом движении — один неподвижный кадр.

visibility.ts
import type { WebGLRenderer } from 'three';

// 3D-сцена не должна сажать батарею: рисуем, только пока её видно
export function renderOnlyWhenVisible(
  renderer: WebGLRenderer,
  canvas: HTMLCanvasElement,
  draw: (time: number) => void,
) {
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduced) {
    draw(0); // в системе отключено движение: один неподвижный кадр
    return;
  }
  new IntersectionObserver(([entry]) => {
    renderer.setAnimationLoop(entry?.isIntersecting ? draw : null);
  }).observe(canvas);
}

Вопросы о Three.js и WebGL

Чем WebGL отличается от Three.js?

WebGL — низкоуровневый доступ браузера к видеокарте; Three.js — библиотека, которая превращает его в сцены, камеры и модели.

Будет ли 3D работать на телефонах?

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

Вредит ли 3D продвижению в поиске?

Нет, если содержание остаётся в HTML, а сцена грузится лениво и не тормозит первый экран.

Откуда берутся 3D-модели?

Их делают в Blender или другом редакторе либо готовят из CAD-файлов производителя, затем выгружают в glTF и сжимают.

Что такое WebGPU и нужен ли он?

Стандарт графики нового поколения. Three.js умеет его использовать с откатом на WebGL, поэтому сайт работает в любом браузере.

Three.js или Spline?

Spline быстр для декоративного 3D от дизайнера; Three.js даёт полный контроль над весом, взаимодействием и логикой.

Можно ли использовать Three.js с React?

Да, через React Three Fiber: сцена описывается компонентами.

Не лучше ли видео, чем 3D?

Если взаимодействия нет — часто да. 3D выигрывает, когда посетителю нужно вращать, выбирать или исследовать.

Форма

3D для
вашего сайта

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

Или пишите на [email protected]