První scéna

V této části si s pomocí Three.js vytvoříme jednoduchou 3D scénu. Vytvoříme si model kostky, umístíme ji do scény a tu vykreslíme na canvas. Nebudeme zabíhat do žádných velkých detailů, cílem této části je hlavně to, abyste si zkusili jak se s Three.js pracuje a začali jej používat. Do detailnějšího vysvětlení různých věcí týkající se Three.js se pustíme až v dalších částech.

Instalace Three.js

Než začneme Three.js používat, tak si jej samozřejmě musíme nainstalovat. Máme více možností jak to udělat. Nejlepší je pravděpodobně nainstalovat si jej přes NPM a použít nějaký sestavovací nástroj jako je Webpack. To ale není tak jednoduché a proto to necháme až na další část. V této části si Three.js stáhneme ručně a na naši webovou stránku jej přidáme prostřednictvím script tagu.

Three.js můžeme stáhnout z oficiálních stránek. V menu v sekci Code je tam možnost download.

Stažení Three.js

Po kliknutí na možnost download se vám stáhne zazipovaný soubor, který obsahuje spoustu souborů a složek. Vlastně se vám stáhne GitHub repozitář Three.js. Máte tedy kromě jednoho souboru pro produkci k dipozici i zdrojový kód. Mi potřebujeme jen tento jeden soubor a ten se nachází ve složce build. Jmenuje se three.min.js. Tento soubor si vezměte a vložte do nějaké složky, ve které budete dělat svoji první aplikaci s Three.js. Poté v této složce vytvořte html soubor, do kterého si script připojte.

<!DOCTYPE html>
<html lang="cs">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js - První scéna</title>
</head>
<body>
    <script src="./three.min.js"></script>
</body>
</html>

Vyrenderování kostky

Three.js jsme si přidali na naši webovou stránku a můžeme jej tedy začít používat. Vytvoříme si nový JavaScript soubor a připojíme si jej na stránku. Musíme jej ale připojit až po knihovně Three.js abychom ji mohli v našem kódu používat. Můžete jej nazvat třeba jako main.js. A rovnou také můžeme na stránce vytvořit canvas, do kterého budeme renderovat. Nastavíme mu nějakou velikost a id, pomocí kterého jej v JavaScriptu získáme.

<!DOCTYPE html>
<html lang="cs">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js - První scéna</title>
</head>
<body>
    <canvas width="700" height="400" id="WebGLCanvas"></canvas>
    <script src="./three.min.js"></script>
    <script src="./main.js"></script>
</body>
</html>

V našem JavaScript souboru bychom měli mít přístup k objektu THREE, pomocí kterého můžeme Three.js používat. Můžeme například vytvořit novou scénu.

const scene = new THREE.Scene();

Poté můžeme do scény třeba přidat nějaký objekt. Ten vytvoříme pomocí třídy Mesh, které při vytváření její instance předáme geometrii a materiál, které by měl náš objekt mít. Zatím vám nebudu vysvětlovat žádné větší detaily. Do toho se pustíme až v dalších částech. Pouze si zkopírujte kód z následující ukázky. V této části ještě nemusíte úplně vědět jak to přesně funguje.

const scene = new THREE.Scene();

// vytvoření geometrie pro objekt
const geometry = new THREE.BoxGeometry(1, 1, 1);
// vytvoření materiálu pro objekt
const material = new THREE.MeshBasicMaterial({
    color: 0x78E8FA
});
// vytvoření objektu (kostky)
const cube = new THREE.Mesh(geometry, material);

// přidání objektu do scény
scene.add(cube);

Pokud si chceme v reálném světě něco vyfotit, tak k tomu potřebujeme fotoaparát. Ve Three.js je to podobně. Abychom si mohli náš objekt vykreslit na canvas, tak k tomu potřebujeme kameru. Kamera vlastně určuje, kde se ve scéně nacházíme a kam se díváme. Existuje více typů kamer a podíváme se na ně v samostatné části. Pro náš jednoduchý příklad teď použijeme perspektivní kameru, která se pravděpodobně používá nejvíce. Vytvoříme ji pomocí třídy PerspectiveCamera a přidáme ji do scény stejným způsobem jako předešlý objekt. Při vytváření kamery potřebujeme vědet velikost canvasu, proto si jej v JavaScriptu získáme podle id, které jsme mu v HTML nastavili a jeho velikost si zjistíme. Opět nemusíte vědět jak to funguje a co jednotlivé možnosti znamenají, to si vysvětlíme v jiné části.

/* ... */

// při vytváření kamery potřebujeme znát velikost canvasu,
// proto si jej získáme podle id, které jsme mu nastavili
const canvas = document.getElementById("WebGLCanvas");

// vytvoření kamery
const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight);

// přidání kamery do scény
scene.add(camera);

Na konec ještě potřebujeme renderer. Jeho úkolem je vzít kameru a scénu a vekreslit scénu na canvas podle toho kde se kamera nachází a kam se dívá. Rendererů je více ale naprosto nejčastěji používaným rendererem je WebGLRenderer. Potom je třeba ještě CSS3DRenderer, který pracuje namísto canvasu s DOM elementy, nebo SVGRenderer, který renderuje grafiku jako SVG. Tyto renderery se ale tolik nepoužívají a proto bychom si je museli do našeho projektu přidat samostatně. Můžete je najít v zazipovaném souboru, který jste si stáhli. Mi samozřejmě použijeme WebGLRenderer. Při jeho vytváření předáváme do konstruktoru canvas, který bude renderer používat k vykreslování. Po vytvoření rendereru můžeme zavolat metodu render, které předáme scénu a kameru a scéna se nám na canvas vykreslí.

/* ... */

// vytvoření rendereru
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
});

// vykreslení (vyrenderování) scény na canvas
renderer.render(scene, camera);

Pokud si stránku otevřete v prohlížeči, tak na canvasu uvidíte jen černou barvu. Objekt, který jsme si do scény přidali neuvidíte. To je proto, že se kamera nachází na stejném místě jako objekt. Neměnili jsme pozici kamery ani objektu, jen jsme je do scény přidali, takže se oba nacházejí na souřadnicích [0, 0, 0]. Pokud nevíte co tyto souřadnice znamenají, tak nevadí, vysvětlíme si je v jiné části. Musíme tedy změnit pozici kamery nebo objektu. Posuneme třeba kameru trochu dozadu (směrem k nám). Kamera obsahuje vlastnost position, která určuje její pozici ve scéně. Position je instance třídy Vector3 a obsahuje hodnoty X, Y, a Z. Obsahuje tři nějaká čísla a v případě position hodnota X určuje pozici horizontálně, hodnota Y vertikálně a hodnota Z od nás nebo směrem k nám. Nastavením kladného čísla hodně Z posuneme kameru dozadu (směrem k nám).

/* ... */

const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight);
// posunutí kamery dozadu (směrem k nám)
camera.position.z = 3;

/* ... */

Pokud si stránku otevřete teď, tak byste již na canvasu měli vidět vykreslenou modrou kostku.

Pokud se chcete ujistit že se opravdu jedná o kostku a ne jen o čtverec, tak můžete kameru třeba posunout trochu doprava a nahoru. Potom byste měli vidět i její jiné strany.

/* ... */

const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight);
camera.position.z = 3;
camera.position.x = 1;
camera.position.y = 1;

/* ... */

Co je potřeba k vytvoření základní scény

V předchozím příkladu, ve kterém jsme renderovali kostku, jste mohli vidět že k vytvoření a vykreslení základní scény je potřeba scéna, nějaké objekty (meshe), kamera a renderer. Na závěr této části bych u těchto věcí chtěl ještě krátce popsat k čemu slouží.

Scéna

Scéna představuje takový container, do kterého přidáváme objekty, světla, načtené 3D modely a tak podobně. V určitém okamžiku ji předáme rendereru k vyrenderování a vykreslí se nám na canvas.

// vytvoření scény
const scene = new THREE.Scene();

// přidání objektů do scény
scene.add(box1, light);

Mesh

Mesh je kombinace geometrie (tvaru) a materiálu (jak to vypadá). Při jeho vytváření mu předáme jakou geometrii představuje a jaký se má na geometrii aplikovat materiál. Po vytvoření meshe jej můžeme přidat do scény, kterou potom můžeme vyrenderovat na canvas pomocí rendereru.

// vytvoření geometrie
const geometry = new THREE.BoxGeometry(1, 1, 1);
// vytvoření materiálu
const material = new THREE.MeshBasicMaterial({
    color: 0x78E8FA
});

// vytvoření meshe podle geometrie a materiálu
const cube = new THREE.Mesh(geometry, material);

Kamera

Kamera slouží jako bod, ze kterého se díváme na scénu. Můžeme si ji představit stejně jako fotoaparát, který používáme když něco fotíme. Můžeme mít i více kamer a přepínat se mezi nimi, ale to se tak často nedělá, protože můžeme jednoduše změnit pozici kamery. Existuje více typů kamer, později se na ně podíváme v samostatné části. V našem příkladu při renderování kostky jsme používali perspektivní kameru. To znamená, že objekty vzadu budou malé a ty vepředu větší, stejně jako v reálném světě.

// vytvoření kamery
const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight);

// přidání kamery do scény
scene.add(camera);

Renderer

Renderer slouží k vykreslení (vyrenderování) scény na canvas z výhledu kamery. Jak jsem psal, tak existuje i více typů rendererů, ale ten nejpoužívanější je WebGLRenderer. O ostatních v podstatě ani nemusíte vědět, pokud nebudete chtít pracovat s 3D grafikou třeba prostřednictvím CSS nebo SVG. Po vytvoření rendereru můžeme použít metodu render, které předáme scénu a kameru z jejíhož výhledu chceme scénu vykreslit. Po zavolání této metody se nám scéna vykreslí na canvas.

// vytvoření rendereru
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
});

// vykreslení (vyrenderování) předané scény
// na canvas podle výhledu předané kamery
renderer.render(scene, camera);

To by bylo pro tuto část vše. Zkusili jste si Three.js knihovnu používat a dozvědeli jste se k čemu slouží scéna, mesh, kamera a renderer. V budoucích částech tutoriálu se u těchto věcí pustíme do většího detailu. V příští části si Three.js nainstalujeme přes NPM a použijeme nástroj jménem Webpack. Three.js se nám tak bude používat lépe než jak jsme jej používali v této části. Používání Three.js tak, jak jsme jej používali v této části má totiž pár omezení o kterých se v další části dozvíte.