Как использовать WebGL для интерактивной 3D-графики

Приходилось ли вам взаимодействовать с 3D-моделями на экране компьютера? Скорее всего, да. Если вы играли в современные видеоигры на консоли или компьютере, то уже знакомы с этой концепцией.

Речь идет не о таких старых играх, созданных в 2D-canvas, как Super Mario и Donkey Kong. Это касается 3D-видеоигр, предоставляющих доступ к различным моделям внутри 3D-canvas, с которыми можно взаимодействовать.

Они разрабатываются с помощью игровых движков, использующих законы физики и математики для создания захватывающего 3D-пространства, с которым игрок может взаимодействовать. Как правило, для их разработки применяются низкоуровневые языки программирования, такие как C++. Большинство крупных компаний, работающих в игровой индустрии, используют собственные игровые движки, созданные на основе C++.

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

Этого можно достичь, используя WebGL.

Что такое WebGL?

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

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

Одним из инструментов, который оказал большое влияние на мою работу в этой области, является Three.js.

Three.js  —  это библиотека JavaScript, которая позволяет создавать и отображать 3D-графику в браузере с помощью WebGL.

Эта библиотека:

  • быстрая;
  • легкая;
  • простая в использовании, что позволяет создавать сложную 3D-графику.

Three.js также хорошо подходит для разработки игр благодаря поддержке WebGL, что помогает создавать быструю и плавную 3D-графику, запускаемую в браузере. Конечно, у вас не получится выпустить обновленную версию игры Grand Theft Auto, но с помощью Three.js вы станете лучше разбираться в 3D-разработке.

Создание 3D-графики с помощью WebGL и Three.js

Одним из преимуществ библиотеки Three.js является легкость использования с самого начала работы.

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

1. Найдите 3D-модель обуви

Вы можете либо создать собственную 3D-модель с помощью ПО для 3D-моделирования, либо найти готовую в интернете.

Для этого примера будет использована готовая модель с сайта Three.js.

2. Создайте canvas и рендерер

Canvas нужен для создания 3D-среды, а рендерер  —  для анимации и отображения 3D-пространства.

//... HTML
<canvas class="webgl"></canvas>

//... JavaScript
const canvas = document.querySelector('canvas.webgl');

/**
* Рендерер
*/
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
})
// Размер окна рендерера
renderer.setSize(window.innerWidth, window.innerHeight);
// Соотношение пикселей установлено для правильного рендеринга сцены на всех устройствах
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

3. Создайте сцену (трехмерное визуальное пространство)

Работа в Three.js начинается с создания сцены, которая похожа на контейнер. Вы помещаете в нее объекты, модели и даете указание Three.js отрендерить эту сцену.

const scene = new THREE.Scene();

4. Добавьте камеру в сцену

Есть два типа камеры: перспективная и ортогональная.

Перспективная камера предназначена для имитации того, как видит человеческий глаз.

Перспективная камера является наиболее распространенным режимом проекции, применяемым для рендеринга 3D-сцены, поэтому будем использовать именно ее.

/**
* Камера
*/
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
scene.add(camera)

После успешного создания сцены и камеры нужно отрендерить их в окне. Обычно этот шаг выполняется в конце, но я хочу показать вам загруженную модель на изображениях ниже.

const animate = () =>
{
// Рендер
renderer.render(scene, camera)

// Повторите вызов tick на следующем кадре
window.requestAnimationFrame(animate)
}

animate();

5. Загрузите 3D-модель

Для открытия файла .gltf и добавления пути к нему будем использовать GLTFLoader. Большинство 3D-моделей поставляются в формате .gltf, но есть и другие, например .stl.glb.obj и т.д.

const loader = new THREE.GLTFLoader();

loader.load(
'shoePath', (gltfFile) => {
scene.add(gltfFile.scene);
});

На данном этапе получится нечто подобное:

Загруженная 3D-модель ботинка

Мы видим, как кажется, черно-белое изображение ботинка на белом фоне. Причина в том, что в сцене пока нет освещения. Материал 3D-модели реагирует на свет так же, как планета реагирует на излучение звезды. Чтобы корректно изобразить 3D-модель, необходим свет.

6. Добавьте освещение

В файле three.js есть шесть видов света, но в данном примере будем использовать только два из них:

  • Ambient Light  —  общий свет, который освещает все объекты в сцене;
  • Directional Light  —  направленный (“солнцеподобный”) свет, который излучается в определенном направлении.
// Первый параметр - цвет света; второй - его интенсивность.
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
// Добавляем свет в сцену
scene.add(ambientLight, directionalLight);

А вот обновленный canvas:

Загруженная модель с освещением

Теперь нужно поработать с фоном, чтобы правильно отразить свет, который идет сверху, попадает одновременно на ботинок и фон и при этом отображает тень модели.

Для этого необходимо создать сетку с помощью плоскостной геометрии.

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

7. Добавьте плоскостную геометрию

const planeMaterial = new THREE.MeshStandardMaterial( { color: params.material, specular: 0x101010 } );
const planeGeometry = new THREE.PlaneGeometry(50, 50);
const planeMesh = new THREE.Mesh(planeGeometry, material);

planeMesh.rotation.x = - Math.PI / 2;
planeMesh.position.y = - 0.5;
Объект на плоскости

По умолчанию плоскостная геометрия создается вертикально в центре экрана. Поэтому нужно добавить математику для вращения, а именно Math.PI / 2 по оси x, чтобы повернуть объект на 90 градусов по часовой стрелке, если смотреть сверху, как показано на рисунке.

8. Создайте тень

Чтобы спроецировать тень модели на плоскость, вставляем в код эти строки для 3D-модели, геометрии плоскости, а также рендерера:

// ...
loader.load(
'shoePath', (gltfFile) => {

// создайте постоянную "сетку", чтобы сделать ее многоразовой
const mesh = gltfFile.scene;
mesh.castShadow = true;
//... остальной код

});

// ... при создании плоскости
planeMesh.receiveShadow = true;

//... для рендерера
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

В итоге, после определенных модификаций фона, затуманенности сцены и плоскостной геометрии для придания лучшей стилизации, увидим следующее:

Полностью загруженная модель

И это все! С помощью всего нескольких строк кода можно отобразить 3D-обувь на веб-странице и позволить пользователям взаимодействовать с ней.

В WebGL есть еще много интересного, и возможности 3D-графики в веб-разработке безграничны.

Вы можете протестировать код в CodeSandBox и StackBlitz. Я добавил несколько помощников для управления освещением, а также использую элементы управления для перемещения вокруг объекта под любым углом.

Модель ботинка

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Egi Mata: 3D Web Development: How to use WebGL for Interactive 3D Graphics

Предыдущая статьяCodeGPT: расширение VSCode с функциями ChatGPT
Следующая статьяФормирование эффективной и целостной культуры ревью кода