Вивчаємо Three.js.Глава 2: Робота з основними компонентами, з яких состоітThree.js-сцена

      Всім привіт!
У попередньому розділі ми познайомилися з основами бібіліотекіThree.js. Побачили кілька прикладів і створили свою першу повноцінну Three.js сцену. У цьому розділі ми трохи глибше заглибимося в цю бібліотеку і спробуємо більш детально пояснити основні компоненти, складові Three.js сцену. У цьому розділі ви дізнаєтеся про таке:
 
     
  1. які компоненти використовуються в Three.js сцені
  2.  
  3. що можна робити з об'єктом THREE.Scene ()
  4.  
  5. яка різниця між орфографічною і перспективною камерами
  6.  
Почнемо ми з того, що подивимося, як же можна створити сцену і додати на неї об'єкти.
 
 
 
 

Створення сцени

У попередньому розділі ми вже створювали об'єкт THREE.Scene (), так що ви вже знайомі з цим компонентом бібліотеки Three.js. Так само ми побачили, що для нормального відображення сцени нам необхідно три компоненти:
 
     
  1. світло: він надає вплив на матеріали і використовується при створенні ефекту тіні
  2.  
  3. камера: цей компонент визначає, що буде відображатися на сцені
  4.  
  5. мотор об'єкти: це основні об'єкти, які відображаються в перспективі камери: куби, сфери і т.д.
  6.  
Об'єкт THREE.Scene () виступає в якості контейнера для всіх цих компонентів. У цього об'єкта самого по собі не надто багато опцій і функцій.
 
 
Базова функціональність сцени
Кращий спосіб вивчити функціональність сцени — це подивитися на прикладі. У исходниках до цієї чолі (chapter-02) ви можете знайти приклад 01-basic-scene.html. Я буду використовувати цей приклад, щоб пояснити функції і опції, якими володіє сцена. Якщо ми відкриємо цей приклад в браузері, то побачимо приблизно таке:
 
 
 
Це трохи схоже на те, що ми бачили в попередньому розділі. Незважаючи на те, що сцена виглядає дещо порожній, вона вже містить кілька об'єктів. Дивлячись на наступний початковий код, ми бачимо, що ми використовували функцію
Scene.add(object)
для об'єкта
THREE.Scene()
, додавши тим самим такі об'єкти як
THREE.Mesh
(це площина, яку ви бачите),
THREE.SpotLight
і
THREE.AmbientLight
. Об'єкт
THREE.Camera
додається автоматично самою бібліотекою Three.js, коли ви визуализируете сцену, але він так само може бути доданий вручну, якщо ви того захочете.
 
 
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, 
	window.innerWidth / window.innerHeight, 0.1, 1000);
...
var planeGeometry = new THREE.PlaneGeometry(60,40,1,1);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
...
scene.add(plane);
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
...
var spotLight = new THREE.SpotLight( 0xffffff );
...
scene.add( spotLight );

Перш ніж ми більш детально почнемо розглядати об'єкт THREE.Scene (), я б хотів розповісти, що ви можете зробити в демонстраторів, а вже потім почнемо розбиратися в коді. Відкрийте приклад в браузері і подивіться чи не елементи управління у верхньому правому куті, ось що можна зробити:
 
 
 
За допомогою цих елементів керування можна додати кубик на сцену, видалити останній доданий кубик зі сцени і відобразити число всіх елементів, які містить сцена. Ймовірно, ви помітили, що, коли ви тільки запускаєте приклад, то на сцена вже знаходиться 4 об'єкта. Це наша площину, джерело розсіяного світла, джерело точкового світла і камера, про яку ми згадували раніше. Далі ми більш детально розглянемо кожен з компонентів у блоці управління і почнемо з найпростішого: з функції
addCube
():
 
 
this.addCube = function() {
	var cubeSize = Math.ceil((Math.random() * 3));
	var cubeGeometry = new THREE.CubeGeometry(cubeSize,cubeSize,cubeSize);
	varcubeMaterial = new THREE.MeshLambertMaterial(
		{color: Math.random() * 0xffffff });
	var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
	cube.castShadow = true;
	cube.name = "cube-" + scene.children.length;
	cube.position.x=-30 + Math.round((Math.random() * planeGeometry.width));
	cube.position.y= Math.round((Math.random() * 5));
	cube.position.z=-20 + Math.round((Math.random() * planeGeometry.height));
	scene.add(cube);
	this.numberOfObjects = scene.children.length;
};

Цей фрагмент коду повинен досить легко сприйматися в даний час. Тут не вводиться багато нових понять. При натисканні на кнопку addCube , створюється новий екземпляр
THREE.CubeGeometry
з випадковим розміром від нуля до трьох. Крім довільного розміру, куб також отримує випадкове положення на сцені і колір.
Новим у цьому фрагменті коду є те, що ми задаємо ім'я кубу за допомогою атрибуту
name
. Його ім'я задається як
cube
— і число вже наявних на сцені кубів (показується за допомогою атрибуту
scene.children.length
). Таким чином, виходять імена
cube-1, cube-2, cube-3
і так далі. Ім'я може бути корисно для налагодження, але також може використовуватися для прямого пошуку об'єкта на вашій сцені. Якщо ви використовуєте функцію
Scene.getChildByName(name)
, то ви можете безпосередньо отримати об'єкт і, наприклад, змінити його розташування. Мінлива
numberOfObjects
використовується нашим керуючим інтерфейсом як розмір списку числа елементів на сцені. Тому, коли ми додаємо або видаляємо об'єкт, то ми встановлюємо цю змінну в значення, рівне новому кількістю елементів на сцені.
Наступна функція, яку ми можемо викликати з керуючого інтерфейсу це
removeCube
, і, як випливає з назви, клікнувши на цю кнопку, зі сцени видаляється останній доданий куб. Нижче показано, як реалізована дана функція:
 
 
this.removeCube = function() {
	var allChildren = scene.children;
	var lastObject = allChildren[allChildren.length-1];
	if (lastObjectinstanceofTHREE.Mesh) {
		scene.remove(lastObject);
		this.numberOfObjects = scene.children.length;
	}
}

Щоб додати об'єкт на сцену, ми будемо використовувати функцію
add
(). А щоб видалити об'єкт зі сцени, як це не дивно, функцію
remove
(). У цьому фрагменті коду ми використовували властивість
children 
об'єкта
THREE.Scene()
, щоб отримати останній об'єкт, який був доданий. Нам також необхідно перевірити, щоб об'єкт був
Mesh 
об'єктом, щоб уникнути видалення камери і світла. Після того, як ми видалили об'єкт, ми в черговий раз повинні оновити елемент керуючого інтерфейсу, який відображає кількість об'єктів на сцені.
Остання кнопка на нашемGUI позначена як outputObjects . Ви, напевно, вже натиснули на неї, і, здавалося б, нічого не сталося. Те, що робить ця кнопка, це роздруковує всі об'єкти, які в даний час відображені на нашій сцені і виводить їх в консоль веб-браузера, як показано нижче:
 
 
 
Код для виведення інформації в лог консолі використовує вбудований об'єкт
console
, як показано нижче:
 
 
this.outputObjects = function() {
	console.log(scene.children);
}

Це дуже зручно для налагодження; особливо коли ви називаєте свої об'єкти, це дуже зручно при пошуку проблем конкретних об'єктів на сцені. Наприклад, властивості об'єкта з ім'ям
cube-17
будуть виглядати наступним чином:
 
 
__webglActive: true
__webglInit: true
_modelViewMatrix: THREE.Matrix4
_normalMatrix: THREE.Matrix3
_vector: THREE.Vector3
castShadow: true
children: Array[0]
eulerOrder: "XYZ"
frustumCulled: true
geometry: THREE.CubeGeometry
id: 20
material: THREE.MeshLambertMaterial
matrix: THREE.Matrix4
matrixAutoUpdate: true
matrixRotationWorld: THREE.Matrix4
matrixWorld: THREE.Matrix4
matrixWorldNeedsUpdate: false
name: "cube-17"
parent: THREE.Scene
position: THREE.Vector3
properties: Object
quaternion: THREE.Quaternion
receiveShadow: false
renderDepth: null
rotation: THREE.Vector3
rotationAutoUpdate: true
scale: THREE.Vector3
up: THREE.Vector3
useQuaternion: false
visible: true
__proto__: Object

До цих пір ми розглядали такі функції для сцени:
 
     
  1. Scene.Add()
    : цей метод додаємо об'єкт на сцену
  2.  
  3. Scene.Remove(
    ): цей метод видаляє об'єкт зі сцени
  4.  
  5. Scene.children()
    : цей метод отримує список всіх дітей об'єкта сцена
  6.  
  7. Scene.getChildByName()
    : цей метод отримує конкретний об'єкт зі сцени за його атрибуту name
  8.  
Це найважливіші функції сцени, які ви будете застосовувати досить часто. Однак, є кілька допоміжних функцій, які можуть вам стати в нагоді, і я хотів би познайомити вас з ними на прикладі коду, який обробляє обертання куба.
Як ви вже бачили в попередньому розділі, ми використовували цикл всередині функції
render 
для візуалізації сцени. Давайте поглянемо на цей же фрагмент коду для цього прикладу:
 
 
function render() {
	stats.update();
	scene.traverse(function(e) {
		if (e instanceofTHREE.Mesh&& e != plane ) {
			e.rotation.x+=controls.rotationSpeed;
			e.rotation.y+=controls.rotationSpeed;
			e.rotation.z+=controls.rotationSpeed;
		}
	});
	requestAnimationFrame(render);
	renderer.render(scene, camera);
}

Тут ми можемо бачити, що використовується функція
THREE.Scene.traverse()
. Ми можемо передати функцію як аргумент функції. Це буде передаватися у функцію і викликатися у кожної дитини сцени. У функції
render
() ми будемо використовувати функцію
traverse
() для оновлення обертання для кожного екземпляра
cube 
(ми явно ігноруємо нашу основну площину). Ми б могли зробити це за допомогою перебору всіх елементів масиву по властивості
children 
в циклі
for
.
Перш ніж зануритися в деталі об'єктів
Mesh 
і
Geometry
, я б хотів показати вам два цікавих властивості, які можна встановити на об'єкті сцени:
fog 
і
overrideMaterial
.
 
 
Додаємо ефект туману на площину
Властивість
fog 
дозволяє додавати ефект туману на нашу сцену. Чим далі об'єкт, тим більше він буде прихований від очей. На наступному скріншоті показано як це виглядає:
 
 
 
Включення властивості туману відбувається в бібліотеці Three.js відбувається дуже легко. Просто додайте наступний рядок коду після того як ви визначили свою сцену:
 
 
scene.fog=new THREE.Fog( 0xffffff, 0.015, 100 );

Тут ми визначили колір туману як білий (0xffffff). Останні два аргументи можуть бути змінені вже після того, як туман з'явиться. Значення 0,015 встановлюється для властивості
near
, а 100 для властивості
far
. За допомогою цих двох властивостей ви можете визначити, де туман буде починатися і як швидко він буде ставати більш щільним. Також існує інший спосіб встановити туман для сцени: для цього нам знадобиться наступне:
 
 
scene.fog=new THREE.FogExp2( 0xffffff, 0.015 );

На цей раз ми не вказували властивості
near 
і
far
, а тільки колір і щільність туману. А взагалі краще самим погратися, щоб розібратися з цими властивостями, і ви отримаєте той ефект, який захочете.
 
 
Використання властивості overrideMaterial
Остання властивість, яке ми розглянемо, буде властивість
overrideMaterial
, воно використовується для фіксації матеріалу всіх об'єктів на сцені. Якщо ви використовуєте це властивість, то, як показано нижче, всі об'єкти, які ви додаєте на сцену, матимуть один і той же матеріал:
 
 
scene.overrideMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});

Результат наведено нижче:
 
 
 
На цьому скріншоті добре видно, що всі екземпляри об'єкта cube візуалізовані за допомогою одного і того ж матеріалу і кольору. У цьому прикладі ми використовували об'єкт
MeshLambertMaterial 
в якості основного матеріалу.
У цьому розділі ми розглянули першу з основних концепцій бібліотеки Three.js: сцену. Найголовніше, що треба пам'ятати, це те, що це в основному контейнер для всіх об'єктів, світла і камери, які ви хочете відобразити. Нагадаємо, найбільш важливі функції і атрибути об'єкта
Scene
.
 
     
  1. add(object)
    : додає об'єкт на сцену, ви також можете використовувати цю функцію для створення групи об'єктів.
  2.  
  3. сhildren
    : повертає список всіх об'єктів, які були додані на сцену, в тому числі камеру і світло.
  4.  
  5. getChildByName(name
    ): коли ви створюєте об'єкт, ви можете дати йому ім'я за допомогою атрибуту
    name
    . Об'єкт
    Scene 
    має функцію, яку можна використовувати для безпосереднього повернення об'єкта з певним ім'ям.
  6.  
  7. remove(object)
    : якщо у вас є посилання на об'єкт на сцені, то ви можете видалити його зі сцени, використовуючи цю функцію
  8.  
  9. traverse(function)
    : атрибут
    children 
    повертає список всіх об'єктів на сцені. За допомогою функції
    traverse 
    можна отримати доступ до цих об'єктів, передаючи функцію зворотного виклику в якості аргументу.
  10.  
  11. overrideMaterial
    : за допомогою цієї властивості можна зробити так, щоб всі об'єкти на сцені використовували один і той же матеріал.
  12.  
У наступних розділах ми уважно розглянемо об'єкти, які можна додати на сцену.
 
 

Робота з геометрією і Mesh-об'єктами

У кожному з прикладів, які ми бачили, використовувалася геометрія і
Mesh 
об'єкти. Наприклад, щоб додати об'єкт
sphere 
на сцену, ми робили наступне:
 
 
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x7777ff);
var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);

Ми визначили форму об'єкта, його геометрію, як цей об'єкт повинен виглядати, властивість його матеріалу, потім все це з'єднали і додали на сцену. У цьому розділі ми трохи докладніше розглянемо геометричні і сполучні об'єкти, почнемо з геометричних.
 
 
Властивості і функції геометрії об'єктів
Бібліотека Three.js поставляється з великим набором готових геометричних об'єктів, які можна додавати на 3D-сцену. Просто додайте матеріал, створіть змінну
Mesh 
і все в принципі готове. Наведемо невеликий приклад:
 
 
 
Геометричні об'єкти в Three.js, як і в більшості інших 3D-бібліотек, в основному це колекція точок у просторі, а так само ряд граней, що пов'язують всі ці точки разом. Візьмемо, наприклад, куб:
 
     
  1. у куба є вісім вершин. Кожна з цих вершин може бути визначена як комбінація координат х, у і z. Отже, кожен куб має вісім точок у просторі. У бібліотеці Three.js ці точки називаються вершинами.
  2.  
  3. у куба є шість сторін з однією вершиною в кожному з кутів. У бібліотеці Thee.js кожна з цих сторін називається гранню.
  4.  
При використанні бібліотеки Thee.js, коли ви створюєте геометричний об'єкт, ви не повинні визначати всі вершини і грані самі. Для куба вам потрібно визначити всього лише його висоту, ширину і глибину. Бібліотек Thee.js використовує цю інформацію і створює правильний геометричний об'єкт з вісьмома вершинами в потрібному положенні. Незважаючи на те, що, зазвичай, при створенні геометричних об'єктів використовують стандартні об'єкти, запропоновані бібліотекою, ви все одно можете створювати об'єкти вручну, визначивши вершини і грані, як показано нижче:
 
 
var vertices = [
	new THREE.Vector3(1,3,1),
	new THREE.Vector3(1,3,-1),
	new THREE.Vector3(1,-1,1),
	new THREE.Vector3(1,-1,-1),
	new THREE.Vector3(-1,3,-1),
	new THREE.Vector3(-1,3,1),
	new THREE.Vector3(-1,-1,-1),
	new THREE.Vector3(-1,-1,1)
	];
var faces = [
	new THREE.Face3(0,2,1),
	new THREE.Face3(2,3,1),
	new THREE.Face3(4,6,5),
	new THREE.Face3(6,7,5),
	new THREE.Face3(4,5,1),
	new THREE.Face3(5,0,1),
	new THREE.Face3(7,6,2),
	new THREE.Face3(6,3,2),
	new THREE.Face3(5,7,0),
	new THREE.Face3(7,2,0),
	new THREE.Face3(1,3,4),
	new THREE.Face3(3,6,4),
	];
var geom = new THREE.Geometry();
geom.vertices = vertices;
geom.faces = faces;
geom.computeCentroids();
geom.mergeVertices();

Цей код показує, як створити простий куб. Ми визначили точки, які складають куб в масив вершин. Ці точки з'єднуються, щоб вийшли трикутні грані, які зберігаються в масиві граней. Наприклад, елемент
newTHREE.Face3(0,2,1)
створює трикутну грань за допомогою точок 0, 2 і 1 з масиву вершин.
На наступному сріншоте показаний приклад, за допомогою якого можна пограти з позиціями вершин:
 
 
 
Цей приклад, як і всі розглянуті раніше приклади, використовує цикл всередині функції
render
. Всякий раз, коли ви міняєте небудь в розкривається блоці управління, куб відображається правильно, на основі змін положення однієї з його вершин. Для підвищення продуктивності, бібліотека Three.js припускає, що геометрія координатної сітки не буде змінюватися з плином часу. Щоб переконатися, що наш приклад працює необхідно додати наступні рядки коду всередину циклу функції
render
:
 
 
mesh.geometry.vertices=vertices;
mesh.geometry.verticesNeedUpdate=true;
mesh.geometry.computeFaceNormals();

У першому рядку даного фрагмента коду ми оновлюємо масив відображуваних вершин в об'єкті
mesh
. Нам не потрібно перенастроювати грані, так як вони як і раніше обмежені тими ж точками, що й раніше. Після того як ми оновили масив вершин, ми повинні явно сказати, що масив вершин необхідно оновити. Ми можемо зробити — це встановивши властивість
verticesNeedUpdategeometry 
в
true
. Нарешті, ми робимо перерахунок граней повністю оновленої моделі за допомогою функції
computeFaceNormals
().
Остання функціональність
Geometry
, яку ми будемо розглядати — це функція
clone
(). Ми згадали, що
geometry 
визначає форму, форму об'єкта, і в поєднанні з матеріалом ми можемо створити об'єкт, який може бути доданий на сцену, а потім відмалювали засобами бібліотеки Three.js. За допомогою функції
clone
(), як слідуємо з назви, ми можемо зробити копію геометрії і використовувати її для створення іншого
mesh
-об'єкта з іншим матеріалом. У попередньому прикладі, ви можете побачити кнопку clone у верхній частині керуючого інтерфейсу, як показано на наступному скріншоті:
 
 
 
Якщо ви натиснете на цю кнопку, то з'явиться клон, який буде мати ту ж геометрію, що і старий об'єкт в даний час, і новий об'єкт створюється з іншого матеріалу і додається на сцену. Код для цього досить тривіальний, але зроблений трохи складніше через матеріалів, які ми використовуємо. Для початку давайте крок за кроком розберемо код, який був використаний для створення матеріалів для куба:
 
 
var materials = [
	new THREE.MeshLambertMaterial( { opacity:0.6,
		color: 0x44ff44,transparent:true } ),
	new THREE.MeshBasicMaterial( { color: 0x000000,
		wireframe: true } )
];

Як можна побачити ми використовували не один матеріал, а масив з двох матеріалів. Причина в тому, що крім показу прозорого куба, мені також хотілося показати вам каркас, так як він ясно показує, де розташовані вершини і грані. Бібліотека Three.js звичайно ж підтримує використання декількох матеріалів при створенні
mesh
-об'єкта. Для цього ви можете використовувати функцію
SceneUtils.createMultiMaterialObject()
як показано нижче:
 
 
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom,materials);

У цій функції бібліотека Three.js робить те, що вона не створює один примірник
THREE.Mesh
, а створює один примірник для кожного матеріалу, який ви вказали, і поміщає всі ці об'єкти в групу. Ця група може бути використана також як, як і інші об'єкти на сцені. Ви можете додавати меши, отримувати меши по імені і так далі. Наприклад, щоб додати тіні для всіх дітей у цій групі, ми зробимо наступне:
 
 
mesh.children.forEach(function(e) {e.castShadow=true});

Тепер повернемося до функції clone (), яку ми обговорювали раніше:
 
 
this.clone = function() {
	var cloned = mesh.children[0].geometry.clone();
	var materials = [
		new THREE.MeshLambertMaterial( { opacity:0.6,
			color: 0xff44ff,  transparent:true } ),
		new THREE.MeshBasicMaterial({ color: 0x000000,  
			wireframe: true } )
	];
	var mesh2 = THREE.SceneUtils.createMultiMaterialObject(cloned,materials);
	mesh2.children.forEach(function(e) {e.castShadow=true});
	mesh2.translateX(5);
	mesh2.translateZ(5);
	mesh2.name="clone";
	scene.remove(scene.getChildByName("clone"));
	scene.add(mesh2);
}

Цей шматок коду викликається, при кліці на кнопку clone . Тут ми клонуємо геометрію першої дитини куба. Пам'ятайте, що змінна
Mesh 
складається з двох дітей: меш, який використовує
MeshLambertMaterial 
і меш, який використовує
MeshBasicMaterial
. Виходячи з цієї клонованої геометрії, ми створили новий меш і назвали його
mesh2
.
 
 

Функції та атрибути меша

Ми вже з'ясували, що для створення mesh нам необхідна geometry і один або декілька матеріалів. Як тільки ми отримали меш, ми можемо додати його на сцену і отрендеріть. Є кілька властивостей, які ви можете використовувати, щоб вплинути на те, де з'явиться цей меш на сцені. У першому прикладі ми розглянемо наступний набір властивостей і функцій:
 
     
  1. position
    : визначає положення цього об'єкта стосовно позиції його батька. Найчастіше батьком об'єкта є об'єкт
    THREE.Scene()
  2.  
  3. rotation
    : c допомогою цієї властивості можна задати обертання об'єкта навколо однієї з його осей
  4.  
  5. scale
    : це властивість дозволяє масштабувати об'єкт по осях х, у і z
  6.  
  7. translateX(amount)
    : переміщує об'єкт на вказане значення уздовж осі х
  8.  
  9. translateY(amount
    ): переміщує об'єкт на вказане значення вздовж осі у
  10.  
  11. translateZ(amount)
    : переміщує об'єкт на вказане значення уздовж осі z
  12.  
Як завжди, ми розглянемо готовий приклад, який дозволяє пограти всіма цими властивостями, він приведений на наступному скріншоті:
 
 
 
Дозвольте мені розповісти вам про них; почну я зі властивості
position
. Ми вже зустрічали це властивість пару раз, так що давайте швиденько закріпимо його. За допомогою цієї властивості можна задати координати х, у і z об'єкта. Положення об'єкта залежить від його батьківського об'єкта, яким зазвичай виступає сцена. Ми можемо встановити властивість position об'єкта трьома різними способами; кожна з координат може бути безпосередньо встановлена ​​наступним чином:
 
 
cube.position.x=10;
cube.position.y=3;
cube.position.z=1;

Але також ми можемо зробити це однією командою:
 
 
cube.position.set(10,3,1);

Існує також третій варіант. Властивість
position 
за своєю суттю це об'єкт
THREE.Vector.
Це означає, що ми також можемо зробити наступне, щоб розташувати об'єкт в потрібному місці:

cube.postion=new THREE.Vector3(10,3,1)

Мені хотілося б зробити невеликий відступ перед тим, як продовжити розглядати інші властивості
mesh
. Я згадав, що позиція об'єкта встановлюється залежно від положення його батька. У попередньому розділі, присвяченому
THREE.Geometry
для створення багатоскладних об'єктів ми використовували функцію
THREE.SceneUtils.createMultiMaterialObject
. Ще раз зупинюся на тому, що насправді ця функція повертає не один меш, а цілу групу, яка містить окремий меш для кожного матеріалу, заснований на тій же геометрії. У нашому випадку ця група складається з двох мешів. Якщо ми змінимо позицію одного з мешів, який буде створений, то можна буде явно побачити, що це дійсно окремий об'єкт. Однак, якщо ми тепер перемістимо створену групу по колу, то зсув залишиться колишнім. Ці два меша показані на наступному скріншоті:



Ок, наступним у списку є властивість
rotation
. Ви вже помітили, що ми використовували вже це властивість пару раз в цьому, а також в попередніх прикладах. За допомогою цієї властивості можна задати обертання об'єкта навколо однієї з його осей. Ви можете встановити це значення таким же чином, як ми це робили для властивості
position
. Повний оборот, як ви повинні пам'ятати зі школи це 2pi. У наступному прикладі можна подивитися, як це налаштовується:

cube.rotation.x=0.5*Math.PI;
cube.rotation.set(0.5*Math.PI,0,0);
cube.rotation = new THREE.Vector3(0.5*Math.PI,0,0);

Наступним властивістю з нашого обумовленого списку є властивість
scale
. У загальному і цілому назва цього властивість говорить сама за себе. Ви можете масштабувати об'єкт за певною осі. Якщо встановити значення менше ніж один, то об'єкт буде зменшуватися, як показано нижче:



При використанні значень, більших одиниці об'єкт стає більше, це продемонстровано на наступному скріншоті:



В останню чергу в цьому розділі ми поговоримо про переміщують функціях. За допомогою переміщення ви також можете змінити положення об'єкта, але замість визначення його абсолютного положення, в якому ви хочете, щоб він знаходився, ви визначаєте, куди об'єкт повинен переміститися щодо його справжнього становища. Наприклад, у нас є об'єкт
sphere
, який доданий на сцену має координати (1,2,3). Далі ми перемістимо цей об'єкт уздовж осі х за допомогою функції
translateX
(4). Тепер він має координати (5,2,3). Якщо ми хочемо, щоб він прийняв первісне положення, то повинні викликати
translateX
(-4). Використовуючи попередній приклад, ви можете пограти з цими властивостями.

Використання різних камер

У бібліотеці Three.js є два види камер: орфографічна камера і перспективна. Цього разу ми обмежимося розглядом основ роботи з цими об'єктами. Кращий спосіб пояснити різницю між цими камерами — це подивитися на пару прикладів.

Орфографічна камера порівняно з перспективною камерою
У прикладах для цієї главі ви можете знайти приклад під назвою
07-both-cameras.html
. При відкритті цього прикладу, ви побачите щось на зразок наступному скріншоті:



Це називається перспективним видом і є найбільш природним. Як можна бачити з цього скріншота, чим далі знаходяться куби від камери, тим менше вони виявляються.
Якщо ж ми змінимо камеру на інший тип, підтримуваний бібліотекою Three.js, тобто на орфографічну, то побачимо приблизно таке:



З орфографічною камери все кубики виявляються одного розміру; відстань між об'єктом і камерою не має значення. Це часто використовується в 2D-іграх, таких як SimCity 4 і ранніх версіях Цивілізації, як показано на наступному скріншоті:



Найчастіше в наших прикладах ми будемо використовувати перспективну камеру, так як це найбільш близько до реального світу. Перемикання камери насправді дуже просто. Наступний фрагмент коді показує, що відбувається, коли ви клацаєте по кнопці switchCamera в нашому останньому прикладі:

this.switchCamera = function() {
	if (camera instanceof THREE.PerspectiveCamera) {
		camera = new THREE.OrthographicCamera( 
			window.innerWidth / - 16, window.innerWidth / 16,
			window.innerHeight / 16, window.innerHeight / - 16,
			-200, 500 );
		camera.position.x = 2;
		camera.position.y = 1;
		camera.position.z = 3;
		camera.lookAt(scene.position);
		this.perspective = "Orthographic";
	} 
	else {
		camera = new THREE.PerspectiveCamera(45, 
			window.innerWidth / window.innerHeight, 0.1, 1000);
		camera.position.x = 120;
		camera.position.y = 60;
		camera.position.z = 180;
		camera.lookAt(scene.position);
		this.perspective = "Perspective";
	}
};

У цьому лістингу можна побачити, що є різниця в тому, як ми створюємо об'єкт
THREE.PerspectiveCamera
на відміну від об'єкта
THREE.OrthographicCamera
. Для початку давайте розберемо об'єкт
THREE.PerspectiveCamera
. Він приймає такі аргументи:
  1. fov
    : виступає як поле зору. Ця та частина сцени, яку можна побачити з позиції камери. Наприклад, у людей поле зору становить майже 180 градусів, у той час як у деяких птахів воно досягає 360 градусів. Але так як стандартний екран не повністю заповнює наше поле зору, то, як правило, вибирається менше значення. Найчастіше, для ігор, поле зору коливається від 60 до 90 градусів. За умовчанням це величина дорівнює 45 градусам.
  2. aspect
    : це аспект співвідношення між горизонтальним і вертикальним розмірами площі, куди будуть відображатися вихідні дані. Співвідношення сторін визначає різницю між горизонтальним і вертикальним полем зору, як це буде показано на малюнку нижче. Значення за замовчуванням:
    window.innerWidth/window.innerHeight
    .
  3. near
    : це властивість визначає те, як близько до камери бібліотека Three.js повинна візуалізувати сцену. Зазвичай це значення дуже мало, так як ми відображаємо всі об'єкти, заздалегідь визначаючи відстань до них. За замовчуванням ця величина дорівнює 0,1
  4. far
    : це властивість визначає як далеко камера може бачити з позиції камери. Якщо ми встановимо значення цієї властивості як дуже маленьке, то частина нашої сцени може не відобразитися, а якщо занадто велике, то це може вплинути на продуктивність рендеринга. Значення за замовчуванням: 1000.
На наступному малюнку дається хороший огляд того, як ці властивості працюють разом:



Щоб налаштувати орфографічну камеру, ми повинні використовувати інші властивості. Орфографічна проекція не залежить від пропорцій, які ми використовуємо або від поля зору, з яким ми дивимося на сцену. Всі об'єкти відображаються в одному розмірі. Для орфографічною камери нам необхідно визначити куб, який повинен бути відображений. Розглянемо, якими властивостями володіє об'єкт
OrthographicCamera
:
  1. left
    : в документації по Three.js це описано як усічення камери лівої площиною. Ви можете розуміти це як ліва межа. Тобто, якщо ми встановимо це значення в -100, то не побачимо те, що знаходиться лівіше.
  2. right
    : те ж саме, що і для властивості
    left
    , але на цей раз для протилежної сторони екрану. Все, що правіше відображатися не буде.
  3. top
    : верхня межа відображення
  4. bottom
    : нижня межа відображення
  5. near
    : з цієї точки, в залежності від положення камери, буде відображена сцена
  6. far
    : до цієї точки, в залежності від положення камери, буде відображена сцена.
Всі ці властивості показані на наступному малюнку:



Фокусування камери на певній точці
До цих пір ми розглядали, як створювати камеру і що означають різні її властивості. У попередньому розділі ми також дізналися, що камеру необхідно розмістити десь на сцені і що камера буде вказувати на центр відображуваної сцени. Зазвичай камера направлена ​​до центру сцени, використовуючи координати:
position (0,0,0)
. Однак ми можемо легко змінити точку, на яку дивиться камера, це робиться наступним чином:

camera.lookAt(new THREE.Vector3(x,y,z));

Розглянемо приклад, коли камера переміщається, дивлячись на позначену червоним точку, це показано на наступному скріншоті:



Якщо ви відкриєте приклад 08-cameras-lookat.html, то побачите, що сцена рухається зліва направо. Насправді сцена не рухається. Це камера дивиться з різних точок, що дає ефект руху сцени зліва направо. У цьому прикладі ви також можете переключитися на орфографічну камеру. Тут ви побачите, які відбулися зміни і зрозумієте відмінності від перспективної камери.

Висновок

У цій другій вступній главі ми розглянули багато пунктів, і це повинно дати вам хороший огляд того, що таке сцена і чим є найбільш важливі компоненти на ній. У найближчих пару розділах ми будемо більш глибоко розглядати деталі бібліотеки Three.js. Нижче наведені деякі з пунктів, які ви повинні запам'ятати з цієї глави:
  1. Сцена — головний контейнер в бібліотеці Three.js. На неї ви можете додавати будь-які об'єкти.
  2. Біля сцени є трохи спеціальних опцій і властивостей. Найбільш важливі з них дозволяють додавати об'єкти, видаляти їх і працювати з таким атрибутом сцени як
    children
    .
  3. Ви легко можете додати туман на сцену і налаштувати будь-який з пропонованих параметрів цієї властивості.
  4. Геометрія і меши працюють у тісній взаємодії один з одним. Геометрія визначає форму об'єкта, а в поєднанні з матеріалом, ви можете створити меш.
  5. Бібліотек Three.js поставляється з великим набором стандартних геометрій. Однак, можна створювати і свої об'єкти, але це дуже трудомістко, якщо не зроблено через спеціальні алгоритми.
  6. Можна програмно управляти положенням, поворотом і масштабом меша.
  7. За допомогою властивості
    translate 
    ви можете переміщати меш щодо його поточного становища.
  8. Щоб відобразити сцену, нам потрібна камера. У бібліотеці Three.js є два різних види камер: перспективна і орфографічна.
  9. Перспективна камера відображає сцену з точки зору реального світу.
  10. Орфографічна камер робить всі об'єкти однаково розміру і не бере до уваги відстань від камери до об'єктів.
У наступному розділі ми розглянемо різні джерела світла, які доступні в бібліотеці Three.js. Ви дізнаєтеся, як поводяться різні джерела світла, як їх створювати і настроювати.

P.S. Всі недоліки перекладу прошу надсилати в ЛС. Посилання на робочі приклади та вихідні коди з'являться трохи пізніше.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.