Автор оригинала: Hunor Márton Borbély.
Если вы когда-либо хотели построить игру с JavaScript, вы могли бы наступить на Three.js.
Threy.js – это библиотека, которую мы можем использовать для рендеринга 3D-графики в браузере. Все это в JavaScript, поэтому с какой-то логикой вы можете добавить анимацию, взаимодействие или даже превратить его в игру.
В этом руководстве мы пройдем очень простой пример. Мы сделаем 3D-коробку, и пока сделаем, мы узнаем основы Three.js.
Threy.js использует WebGL под капотом для рендеринга 3D графики. Мы могли бы использовать простое WebGL, но это очень сложный и довольно низкий уровень. С другой стороны, Three.js – это как играть с Legos.
В этой статье мы пройдем, как разместить 3D-объект на сцену, настроить освещение и камеру и визуализировать сцену на холсте. Итак, давайте посмотрим, как мы можем сделать все это.
Определите объект сцены
Во-первых, мы должны определить сцену. Это будет контейнер, где мы размещаем наши 3D-объекты и огни. Объект сцены также имеет некоторые свойства, такие как цвет фона. Установка, которая является необязательной, хотя. Если мы не установим его, по умолчанию будет черный.
import * as THREE from "three"; const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000000); // Optional, black is default ...
Геометрия +
Затем мы добавляем нашу 3D-ящик на сцену как сетку. Сетка – это сочетание геометрии и материала.
...
// Add a cube to the scene
const geometry = new THREE.BoxGeometry(3, 1, 3); // width, height, depth
const material = new THREE.MeshLambertMaterial({ color: 0xfb8e00 });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0); // Optional, 0,0,0 is the default
scene.add(mesh);
...Что такое геометрия?
Геометрия – это оказанная форма, которую мы строим – как коробка. Геометрия может быть построена из вершин или мы можем использовать предопределенную.
BoxGeometry – самый простой предварительно определенный вариант. Нам нужно только установить ширину, высоту и глубину коробки, и это она.
Вы можете подумать, что мы не можем добраться до определения ящиков, но многие игры с минималистичным дизайном используют только комбинацию коробок.
Есть и другие предопределенные геометрии. Мы можем легко определить самолет, цилиндр, сферу или даже икосаэдр.
Как работать с материалом
Затем мы определяем материал. Материал описывает появление объекта. Здесь мы можем определить такие вещи, как текстура, цвет или непрозрачность.
В этом примере мы собираемся установить цвет. Есть еще разные варианты материалов. Основное отличие между большинством из них заключается в том, как они реагируют на свет.
Самый простой – это мешбасикматериал. Этот материал вообще не заботится о свете, и каждая сторона будет иметь тот же цвет. Это может быть не лучший вариант, хотя, как вы не можете видеть края коробки.
Самый простой материал, который заботится о свете, – это MeshamberTMaterial. Это рассчитает цвет каждой вершины, который практически каждая сторона. Но это не выходит за пределы этого.
Если вам нужна более точность, есть более продвинутые материалы. Мешфонгматериал не только рассчитывает цвет вершиной, но каждый пиксель. Цвет может измениться в стороне. Это может помочь с реализмом, но и затраты на производительность.
Это также зависит от настроек света и геометрии, если она имеет реальный эффект. Если мы визуализируем коробки и используем направленный свет, результат не будет изменять так много. Но если мы видим сферу, разница более очевидна.
Как расположить сетку
Как только у нас есть сетка, мы также можем разместить его в сцене и установить вращение каждой осью. Позже, если мы хотим анимировать объекты в трехмерном пространстве, мы в основном отрегулируем эти значения.
Для позиционирования мы используем одни и те же единицы, которые мы использовали для настройки размера. Неважно, если вы используете небольшие номера или большие цифры, вам просто нужно соответствовать в своем собственном мире.
Для вращения мы устанавливаем значения в радианах. Поэтому, если у вас есть ваши значения в градусах, вы должны разделить их на 180 °, затем умножьте на PI.
Как добавить свет
Тогда давайте добавим огни. Сетка с базовым материалом не нуждается в свете, так как сетка будет иметь наборный цвет независимо от настроек света.
Но материал Ламберта и материал Phong требуют света. Если нет никакого света, сетка останется во тьме.
... // Set up lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambientLight); ...
Мы добавим два огня – окружающий свет и направленный свет.
Во-первых, мы добавляем окружающий свет. Окружающий свет сияет из каждого направления, давая базовый цвет для нашей геометрии.
Чтобы установить свет окружающей среды, мы устанавливаем цвет и интенсивность. Цвет обычно белый, но вы можете установить любой цвет. Интенсивность – это число от 0 до 1. Два света, которые мы определяем работу в накоплении, так что в этом случае мы хотим, чтобы интенсивность было около 0,5 для каждого.
Направленный свет имеет аналогичную установку, но она также имеет позицию. Положение слов здесь немного вводит в заблуждение, потому что это не значит, что свет исходит из точного положения.
Направленный свет сияет от очень далеко со многими параллельными лучами света, имеющих фиксированный угол. Но вместо определения углов мы определяем направление одного света.
В этом случае он сияет из направления 10,20,0 положения в направлении 0,0,0 координата. Но, конечно, направленный свет – не только один светлый луч, а бесконечное количество параллельных лучей.
Подумайте об этом как о солнце. В меньших масштабах световых лучей солнца также падают параллельно, а позиция Солнца не имеет значения, а скорее его направление.
И это то, что делает направленный свет. Он сияет во всем с параллельными световыми лучами от очень далеко.
... const dirLight = new THREE.DirectionalLight(0xffffff, 0.6); dirLight.position.set(10, 20, 0); // x, y, z scene.add(dirLight); ...
Здесь мы устанавливаем положение света сверху (с значением y) и немного сдвигайте его вдоль оси X. Оси Y имеет наибольшее значение. Это означает, что верхняя часть коробки получает наибольшее количество света, и это будет самая сильнее сторона коробки.
Свет также немного перемещается вдоль оси X, поэтому правая сторона коробки также получит некоторую свет, но меньше.
И поскольку мы не перемещаем положение света вдоль оси Z, передняя сторона коробки не получит никакого света из этого источника. Если бы не был окружающий свет, передняя сторона останется во тьме.
Есть и другие типы света. Например, точечный свет можно использовать для моделирования лампочек. Он имеет фиксированную позицию, и он излучает свет в каждом направлении. И прожектор может быть использован для моделирования прожектора автомобиля. Он излучает свет из одной точки в направлении вдоль конуса.
Как настроить камеру
Пока что мы создали сетку с геометрией и материалом. И мы также настроили свет и добавили на сцену. Нам все еще нужна камера, чтобы определить, как мы смотрим на эту сцену.
Здесь есть два варианта: перспективные камеры и ортографические камеры.
Видеоигры в основном используют перспективные камеры, потому как они работают, похоже на то, как вы видите вещи в реальной жизни. Вещи, которые в дальнейшем, кажется, меньше и вещи, которые прямо перед вами кажутся больше.
С орфографическими прогнозами все будет иметь тот же размер, независимо от того, насколько далеко они с камеры. Ортографические камеры имеют более минимальный, геометрический вид. Они не искажают геометрию – параллельные линии появятся параллельно.
Для обеих камер мы должны определить просмотр Frustum. Это регион в трехмерном пространстве, который будет проецироваться на экран. Все за пределами этого региона не появится на экране. Это потому, что это слишком близко или слишком далеко, или потому что камера не указана навсегда.
С точки зрения проецирования, все в пределах просмотра Frowum проецируется на точку зрения с прямой. Вещи, дальше от камеры, кажутся меньше на экране, потому что с точки зрения вы можете увидеть их под меньшим углом.
... // Perspective camera const aspect = window.innerWidth / window.innerHeight; const camera = new THREE.PerspectiveCamera( 45, // field of view in degrees aspect, // aspect ratio 1, // near plane 100 // far plane ); ...
Чтобы определить перспективную камеру, вам нужно установить поле зрения, что является вертикальным углом с точки зрения. Затем вы определяете соотношение сторон ширины и высоты рамы. Если вы заполните все окно браузера, и вы хотите сохранить его соотношение сторон, то так вы можете сделать это.
Затем последние два параметра определяют, как далеко близкие и дальние самолеты с точки зрения. Вещи, которые слишком близки к камере, будут игнорироваться, и вещи, которые слишком далеко, тоже будут игнорироваться.
... // Orthographic camera const width = 10; const height = width * (window.innerHeight / window.innerWidth); const camera = new THREE.OrthographicCamera( width / -2, // left width / 2, // right height / 2, // top height / -2, // bottom 1, // near 100 // far ); ...
Тогда есть ортографическая камера. Здесь мы не проецируем вещи в сторону одной точки, но к поверхности. Каждая проекционная линия находится параллельно. Вот почему не имеет значения, насколько далеко объекты из камеры, и именно поэтому она не искажает геометрию.
Для ортографических камер мы должны определить, как далеко каждая плоскость с точки зрения. Левая плоскость входит для пяти юнитов влево, а правая плоскость – пять единиц справа, и так далее.
... camera.position.set(4, 4, 4); camera.lookAt(0, 0, 0); ...
Независимо от того, какая мы используем камеру, нам также нужно его расположить и установить ее в направлении. Если мы используем орфографическую камеру, фактические номера здесь не имеют значения. Объекты появятся один и тот же размер, независимо от того, насколько далеко они находятся из камеры. Однако имеет значение, это их пропорция.
Через все это учебное пособие мы видели все примеры через одну и ту же камеру. Эта камера была перемещена одним и тем же устройством вдоль каждой оси, и она выглядит в направлении координаты 0,0,0. Позиционирование орфографической камеры похоже на позиционирование направленного света. Это не фактическая позиция, которая имеет значение, но его направление.
Как сделать сцену
Поэтому нам удалось собрать сцену и камеру. Теперь только последний кусок отсутствует, что отображает изображение в наш браузер.
Нам нужно определить WebGlrenderer. Это кусок, который способен рендурировать фактическое изображение в HTML-холст, когда мы предоставляем сцену и камеру. Это также, где мы можем установить фактический размер этого холста – ширина и высоту холста в пикселях, так как он должен появиться в браузере.
import * as THREE from "three";
// Scene
const scene = new THREE.Scene();
// Add a cube to the scene
const geometry = new THREE.BoxGeometry(3, 1, 3); // width, height, depth
const material = new THREE.MeshLambertMaterial({ color: 0xfb8e00 });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
// Set up lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(10, 20, 0); // x, y, z
scene.add(directionalLight);
// Camera
const width = 10;
const height = width * (window.innerHeight / window.innerWidth);
const camera = new THREE.OrthographicCamera(
width / -2, // left
width / 2, // right
height / 2, // top
height / -2, // bottom
1, // near
100 // far
);
camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
// Add it to HTML
document.body.appendChild(renderer.domElement);И, наконец, последняя строка здесь добавляет этот отобранный холст в наш документ HTML. И это все, что вам нужно сделать коробку. Это может показаться немного слишком много для одной коробки, но большая часть этих вещей нам нужно только настроить один раз.
Если вы хотите продвинуться вперед с этим проектом, посмотрите мое видео YouTube о том, как превратить это в простую игру. В видео мы создаем игру в строительстве. Мы добавляем игровую логику, обработчики событий и анимацию и даже какую-либо физику с Cannon.js.
Если у вас есть какие-либо отзывы или вопросы в этом руководстве, не стесняйтесь Tweet Me @Hunorborbely Или оставьте комментарий на YouTube Отказ