Создание базовых 3D-сцен с помощью Three.js

Мы будем применять один из наиболее классических инструментов веб-разработки  —  тег <script>.

Подготовка базовых файлов

Сначала создадим файл index.html.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>03 - basic scene</title>
</head>
<body>
<script src="./script.js"></script>
</body>
</html>

Затем создаем файл script.js. Код внутри него состоит всего из одной строки:

console.log('Hello Three.js')

Затем дважды кликнем на файле index.html, и он откроется в браузере, установленном по умолчанию на вашем компьютере. Хотя Three.js прекрасно работает в большинстве браузеров, лучше использовать Chrome, поскольку он удобнее в плане разработки и отладки.

Теперь нажимаем F12 на клавиатуре. Откроются инструменты отладки разработчика.

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

Загрузка Three.js

Теперь нужно загрузить библиотеку Three.js на веб-страницу.

Откройте сайт Three.js, нажмите Download, чтобы загрузить последнюю версию библиотеки Three.js, и распакуйте загруженный zip-файл. В нем много файлов, так как это весь репозиторий с автономной документацией и всеми примерами исходного кода. Нам понадобится только один файл.

Распакованная папка будет выглядеть вот так:

Откройте папку build/ и скопируйте из нее файл three.min.js в свой проект.

Теперь в папке проекта должно быть три файла.

Добавьте еще один тег <script> для загрузки библиотеки Three.js.

<script src="./three.min.js"></script>
<script src="./script.js"></script>

Файл three.min.js должен быть загружен до кода, иначе работать с ним не получится.

Как использовать Three.js

В файле script.js у нас теперь есть доступ к переменной с именем THREE. Обратите внимание: THREE написано заглавными буквами.

Если вы используете console.log() для вывода этой переменной, вы увидите много информации.

console.log(THREE)

Переменная THREE содержит большинство классов, методов и свойств, которые могут быть использованы в проекте Three.js.

Чтобы использовать класс, его нужно инстанцировать. Так, чтобы создать сцену, следует написать код const scene = new THREE.Scene (). Если требуется создать 3D-сферу, напишите код const sphereGeometry = new THREE.SphereGeometry(1.5,32,32).

К значению этих классов и параметров инициализации мы еще вернемся.

Создание 3D-сцены

Теперь мы готовы создать 3D-сцену на веб-странице с помощью Three.js.

Для этого понадобится как минимум 4 объекта.

  • Сцена.
  • Несколько 3D-объектов.
  • Камера.
  • Рендерер.

Сцена

Сцена  —  это некое подобие контейнера, в который мы помещаем элементы 3D-мира, такие как модели, освещение, частицы и т. д. Затем в определенный момент Three.js нарисует сцену на canvas с помощью рендерера в сочетании с различными вспомогательными инструментами, такими как камера.

Чтобы создать сцену, используйте класс Scene.

// Сцена
const scene = new THREE.Scene()

3D-объект

В качестве 3D-объекта могут выступать многие элементы, например базовые геометрические формы, импортированные 3D-модели, частицы, освещение и т. д.

Начнем с создания простейшего красного куба.

Куб  —  это тип объекта, который называется “меш” (полигональная сетка). А меш  —  это комбинация геометрии и материалов.

В Three.js встроено множество основных геометрических форм и базовых материалов, но на первый раз упростим задачу и просто создадим куб и базовый материал.

Для создания куба необходимо использовать класс BoxGeometry с 3 параметрами, соответствующими размеру коробки. Речь идет о векторном размере, так что не стоит интерпретировать его, ориентируясь на пиксели. 

// Объект
const geometry = new THREE.BoxGeometry(1, 1, 1)

Для создания базового материала используется класс MeshBasicMaterial. При его инстанцировании мы включаем некоторые параметры для инициализации, такие как свойства цвета, с помощью {}. Конечно, можно установить свойства цвета и после инициализации.

Есть множество способов задать цвета в Three.js. Например, красный цвет может быть выражен либо как шестнадцатеричное число 0xff0000, либо как строка #ff0000, либо как имя цвета, например red. В данном случае мы используем первый вариант.

// Объект
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })

Наконец, задействуем класс Mesh и передаем геометрию и материал в качестве параметров.

// Объект
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const mesh = new THREE.Mesh(geometry, material)

Теперь добавим объект Mesh в сцену с помощью метода сцены add.

scene.add(mesh)

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

Камера

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

У нас также может быть несколько камер в сцене (вспомните, как в кино камера снимает кадр с нескольких позиций), и мы можем переключаться между ними. Однако обычно используется только одна камера.

В Three.js есть два типа камер: перспективная и ортогональная. В большинстве случаев нужна только PerspectiveCamera (ближняя большая и дальняя малая).

Чтобы создать камеру, используется класс PerspectiveCamera. При инстанцировании этого объекта следует указать два основных параметра:

  • FOV;
  • Aspect Ratio.

FOV  —  это угол обзора камеры. Вероятно, вы слышали о широкоугольных объективах. Когда мы используем широкоугольный объектив для съемки, по краям изображения возникает много искажений, хотя в кадр помещается очень много материала. FOV выражается в градусах. В данном случае будем использовать угол в 75 градусов.

Что касается параметра Aspect Ratio (соотношение сторон), то он устанавливается равным ширине элемента canvas, деленной на его высоту.

Не забудьте добавить камеру в сцену!

// Размеры
const sizes = {
    width: 800,
    height: 600
}

// Камера
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
scene.add(camera)

Рендерер

Задача рендерера заключается в том, чтобы отрисовать на canvas то, что камера видит на сцене.

Прежде чем отображать сцену с помощью рендерера, нужно создать canvas в html-файле.

Добавьте тег <canvas> в тело html-файла.

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

Для создания рендерера используем класс WebGLRenderer, который требует предоставить параметр объекта canvas при инстанцировании. С помощью JS-метода document.querySelector можно получить объект canvas, который мы только что создали в html.

Присвоить canvas переменной  —  удачная идея в плане последующего многоцелевого использования.

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

// Canvas
const canvas = document.querySelector('canvas.webgl')

// ...

// Рендерер
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)

Когда весь вышеуказанный код будет написан, обновим текущую страницу и увидим черный элемент canvas шириной 800 пикселей и высотой 600 пикселей.

Первый рендеринг

Подготовьтесь к первому рендерингу: вызовите метод renderer.render и установите сцену и камеру в качестве параметров.

renderer.render(scene, camera)

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

Как правило, мы не видим 3D-объект изнутри. 3D-объект имеет множество свойств, таких как положение, вращение и масштаб. Положение  —  это объект с тремя свойствами, которые представляют собой ось x, ось y и ось z. Задавая их, мы можем перемещать камеру.

Переместим камеру в позицию со значением оси z, равным 3. Обратите внимание, что Three.js использует правостороннюю декартову систему координат.

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
scene.add(camera)

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

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

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


Перевод статьи bin: Build Basic 3D Scenes with Three.js

Предыдущая статьяКак получить данные в нужном формате с помощью Pandas
Следующая статьяНовичкам на заметку: реализация шаблона Singleton в Ruby