КатегорииBabylon.js

Урок 2. Основы Babylon.js

Сегодня мы рассмотрим основы Babylon.js. А точнее такие понятия как движок, сцена, камера, свет, сетка и другие. На практике разберем основные инструменты, а так же векторы, как и где их применяют. Мы так же будем практиковаться в работе с графовыми  структурами и разберем архитектуру Babylon.js.

И так мы рассмотрим следующие темы:

  • Обсудим основные моменты Babylon.js
  • Создадим нашу первую сцену

Babylon.js основы

Движок и сцена

Двигатель является ядром Babylon.js и позволяет создавать и управлять объектами на сцене (3D объекты, освещение, камеры и т.д.). Двигатель можно представить как шлюз для связи с видеокартой (GPU) в то время как сцена предоставляет собой высокоуровневый интерфейс, который работает со следующими объектами:

  • 3D объекты
  • Камеры
  • Свет
  • Система частиц (дым, дождь и другие)
  • Скелетная анимация
  • Пост процессы (эффекты)
  • Материалы
  • Спрайты

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

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

Холст можно объявить так:

<canvas id="render"></canvas>

И по хорошему наш холст надо растянуть на весь экрана:

<style>
        html, body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #render {
            width: 100%;
            height: 100%;
        }
</style>

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

var canvas = document.getElementById('render');

А вот так создается движок:

var engine: BABYLON.Engine = new BABYLON.Engine(canvas);

Сцена:

var scene: BABYLON.Scene = new BABYLON.Scene(engine);

Каждая созданная сцена храниться в массиве engine.scenes.

Для изменения чего либо на сцене, надо перерисовывать изображение на холсте в идеале со скоростью 60 кадров в секунду. Для этого мы должны вызвать функцию движка engine.runRunderLoop(function) это по сути бесконечный цикл, в котором надо вызвать рендеринг сцены:

engine.runRenderLoop(() => {
    scene.render();
});

Функция scene.render(); будет рисовать сцену со всеми объектами на ней.

Камера и освещение

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

Добавление камеры

Есть несколько типов камер. Babylon.js предоставляет несколько типов камер: фиксированная камера, fps камера (для игр от первого лица), вращающаяся камера (поворачивается вокруг точки), геймпад камера (XBOX 360 геймпад) и сенсорная камера (для сенсорных устройств). Все эти камеры могут быть созданы на сцене с минимальных количеством строк кода. Давайте начнем со свободной fps камеры размещенной в точке с координатам (x: 10, y: 20, z: 30). A за одно разберем что такое класс Babylon.Vecror3.

var camera = new BABYLON.FreeCamera('cameraName', new BABYLON.Vector3(10, 20, 30), scene);

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

После создания камеры давайте изменил ее положение и выполним сложение Vector3:

camera.position = new BABYLON.Vector3(10, 0, 10).addInPlace(new BABYLON.Vector3(0, 10, 0));

addInPlace изменяет текущий объект Vector3, если надо создать новый для этого можно использовать функцию add.

Как вы наверняка догадались камера теперь будет висеть по координатам (x: 10, y: 10, z: 10).  Изменение свойства .position не работает для всех камер, особенно для камеры вращения (BABYLON.ArcRotateCamera). Камера вращения поворачивается вокруг точки (которая является объектом камеры) можно представить так:

reader

Куб находиться в положении 0,0,0 и является объектом камеры. Чтобы изменить положение камеры, вы надо вызвать функцию camera.setPosition(положение), эта функция вычислит соответствующие значения для alpha, beta, radius.

Свет

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

var light = new BABYLON.PointLight('lightName', BABYLON.Vector3.Zero(), scene);

Вторым параметром является позиция света. BABYLON.Vector3.Zero() представляет собой статический метод, который представляет собой ярлык для создания экземпляра Vector3 с координатами (x = 0, y = 0, z = 0). Теперь, давайте поиграем с  параметрами светового сигнала:

light.diffuse = new BABYLON.Color3(0, 1, 0);
light.specular = new BABYLON.Color3(1, 0, 0);
light.intensity = 1.0;

Разберем параметры:

  • .diffuse — это цвет света,  в примере он зеленый
  • .specular — цвет отражаемый от поверхности, сейчас он у нас красный
  • .intensity — интенсивность света, которая по умолчанию равна 1

Вот пример результат работы этих параметров, примененного к 3d объекту box:

screenshot_1

А если задать:

light.specular = new BABYLON.Color3(1, 0, 1);

То есть голубой, мы получили бы:

screenshot_2

Добавление mesh

Meshs — это 3D объекты. Babylon.js предоставляет нам статические методы в классе BABYLON.Mesh, которые позволяют создавать примитивны, такие как куб, сфера и т. д. Давайте начнем с куб:

var box = BABYLON.Mesh.CreateBox("cube", 5, scene);

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

box.position = new BABYLON.Vector3(0, 2.5, 0);
box.rotation = new BABYLON.Vector3(0, Math.PI / 4, 0);
box.scaling  = new BABYLON.Vector3(2, 2, 2);

Управление иерархией на сцене

Все объекты на сцене расширяют класс BABYLON.Node и могут иметь одного родителя и множество потомков, по умолчанию каждый вновь созданный объект на сцене является потомком корневого элемента, но это можно изменить через свойство parent, например:

light.parent = camera;

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

Создание первой сцены

Теперь у нас есть все необходимые знания чтобы построить первую сцену. В ней будет камера вращения, точечный свет и куб. Давай создадим класс для этих целей:

class BasicScene {
    public camera: BABYLON.ArcRotateCamera;
    public light: BABYLON.PointLight;
    public box: BABYLON.Mesh;

    private _engine: BABYLON.Engine;
    private _scene: BABYLON.Scene;

    constructor(canvas: HTMLCanvasElement) {
        this._engine = new BABYLON.Engine(canvas);
        this._scene = new BABYLON.Scene(this._engine);

        this.camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 30, BABYLON.Vector3.Zero(), this._scene);
        this.camera.attachControl(canvas, true);

        this.light = new BABYLON.PointLight('light', new BABYLON.Vector3(20, 20, 20), this._scene);
        this.light.diffuse = new BABYLON.Color3(0, 1, 0);
        this.light.specular = new BABYLON.Color3(1, 0, 1);
        this.light.intensity = 1;

        this.box = BABYLON.Mesh.CreateBox('cube', 5, this._scene);
    }

    public setLightParentCamera(): void {
        this.light.parent = this.camera;
    }

    public runRenderLoop(): void {
        this._engine.runRenderLoop(() => {
            this._scene.render();
        });
    }
}

var canvas = document.getElementById('render');

var scena = new BasicScene(canvas);
scena.runRenderLoop();
scena.setLightParentCamera();

Вот такой у нас получился класс с двумя методами runRenderLoop запуск отрисовки и установка камеры в качестве родителя для света setLightParentCamera.

screenshot_4

Итоги

Сегодня мы узнали как работать с основными объектами Babylon.js и создали свою первую сцену. В следующий раз мы узнаем как экспортировать сцены созданные в популярных 3d программах и загрузить в Babylon.js.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *