Přechod do 3D s Three.JS

Všichni jsme chtěli vytvořit ty skvělé webové stránky s těmi úžasnými pohyblivými tvary, které vypadají trojrozměrně. Technologie, která se k tomu používá, se nazývá WebGL. Je to skvělé a dává nám to spoustu svobody a flexibility.

S tím však souvisí i cena. WebGL je komplexní a potřebujeme napsat hodně kódu pro něco tak jednoduchého, jako je krychle. Zde vstupuje do hry three.js. Three.js přidává vrstvu nad WebGL a zároveň umožňuje téměř stejnou míru flexibility.

Toto je první příspěvek ze série tří příspěvků JS. Dnes vám ukážu, jak vytvořit základní tvary ve třech JS.

Můžeme použít Three JS prostřednictvím NPM nebo pomocí CDN.

npm i three

Používáme canvas prvek pro naše 3D postavy. Na kreslení se používá plátno, je to v názvu.

<canvas width="800" height="600" id="threejs-canvas"></canvas>

Vyberme toto plátno pomocí javascriptu.

const canvas = document.querySelector('#threejs-canvas');

Scéna

Nejprve začněme vytvořením Scene . Scéna může být chápána jako kontejner pro naše 3D figurky.

import { Scene } from 'three';

const scene = new Scene();

Části objektů

Základní objekt v Three JS má 3 základní části:

Geometrie

Je to tvar/obrys předmětu. Nyní vytvoříme geometrii krychle.

// Params are width & height
const geometry = new BoxGeometry(1, 1);
Materiál

Je to barva/textura objektu. Kombinací barev a textur můžeme dodat jedinečný vzhled a vzhled. Velmi brzy o tom vytvořím podrobný příspěvek.

const material = new MeshBasicMaterial({ color: 'cyan' });

Můžeme použít různé formáty barev jako hexadecimal , rgb , hsl atd.

Síťovina

Používá se ke spojení geometrie a materiálu. Můžeme jej také použít pro rotace, změnu měřítka, transformace atd.

const cube = new Mesh(geometry, material);

Pokud spustíte kód, uvidíte černé pozadí, ale žádnou kostku. Možná jsme vytvořili kostku, ale nepřidali jsme ji do scény.

scene.add(cube);

Po opětovném spuštění stále není krychle:

Je to proto, že potřebujeme vykreslit naši scénu.

const renderer = new WebGLRenderer({ canvas });

// Dimensions of the canvas
renderer.setSize(800, 600);

Existují různé rendery, ale WebGLRenderer je to, co potřebujeme. Konečně můžeme vidět naši kostku:

Ovládací prvky

Myslím, že by bylo skvělé, kdybychom se mohli po krychli rozhlédnout, tj. podívat se na ni z jiných úhlů. Můžeme to udělat změnou polohy kamery. Mohli bychom to implementovat sami, ale tři JS nám dávají class můžeme použít.

const controls = new OrbitControls(camera, canvas);

// Adding easing for better UX
controls.enableDamping = true;

Nyní zkusme jiné tvary:

Koule

// The first argument is the radius
const geometry = new SphereGeometry(1);
const material = new MeshBasicMaterial({ color: 'cyan' });
const sphere = new Mesh(geometry, material);

scene.add(sphere);

Pokud spustíme kód, dostaneme něco takového:

Jak vidíte, okraje jsou zubaté. Lidé, kteří používali 3D softwarové nástroje, jako je mixér, 3d max atd., budou vědět, proč se to děje. Je to proto, že nám chybí detaily na kouli, které jsou nezbytné pro vytvoření hladké koule. Ve skutečnosti vše, co vytvoříme ve třech JS, je vyrobeno z trojúhelníků. Chceme tedy zvýšit počet trojúhelníků (nebo segmentů podle dokumentů).

Je důležité, abychom to nepřeháněli, protože množství, které musí GPU vypočítat, je přímo úměrné počtu segmentů. Doporučil bych mírně zvýšit hodnotu, dokud většina ostrých hran nezmizí. Ovládací prvky ve většině případů slouží k ladění a uživatel bude mít pravděpodobně pevný úhel kamery.

const geometry = new SphereGeometry(1, 32, 32);
const material = new MeshBasicMaterial({ color: 'cyan' });
const sphere = new Mesh(geometry, material);

scene.add(sphere);

Nyní máme pěknou a hladkou kouli:

Torus

Většina kódu je stejná, jen musíme změnit třídu:

// Params is the radius of the torus, radius of inner circle
const geometry = new TorusGeometry(1, 0.2);
const material = new MeshBasicMaterial({ color: 'cyan' });
const torus = new Mesh(geometry, material);

scene.add(torus);

Pokud spustíme kód, můžeme vidět, že torus postrádá nějaké podrobnosti (stejný problém, jaký jsme měli s koulí). Pojďme k tomu přidat další segmenty.


const geometry = new TorusGeometry(1, 0.2, 32, 32);
const material = new MeshBasicMaterial({ color: 'cyan' });
const torus = new Mesh(geometry, material);

scene.add(torus);

Tam to vypadá mnohem lépe:

Kužel

// Radius of bottom, height
// I've added segments to give it a smooth texture
const geometry = new ConeGeometry(1, 2);
const material = new MeshBasicMaterial({ color: 'cyan' });
const cone = new Mesh(geometry, material);

scene.add(cone);

Vypadá to takto:

Jak vidíte, máme opět problém se segmentem. Pojďme to napravit:

const geometry = new ConeGeometry(1, 2, 32, 32);
const material = new MeshBasicMaterial({ color: 'cyan' });
const cone = new Mesh(geometry, material);

scene.add(cone);

A náš pěkně vypadající kužel:

TorusKnot

To je zajímavý tvar a myslím, že je cool a jedinečný.

const geometry = new TorusKnotGeometry(1, 0.2, 128, 128);
const material = new MeshBasicMaterial({ color: 'cyan' });
const torusKnot = new Mesh(geometry, material);

scene.add(torusKnot);

Existuje mnoho dalších geometrií, které jsou zde dostupné ve třech JS.

Panely ladění

To se opravdu hodí, když chceme provést malé změny, abychom vyzkoušeli barvy, pozice, úhly atd. Rád k tomu používám dat.gui. Pojďme to nainstalovat:

npm i dat.gui

Dále musíme inicializovat GUI:

import { GUI } from 'dat.gui';

const gui = new GUI(); 

Nyní vidíme panel vpravo nahoře:

Máme vlastnost nazvanou wireframe na našem objektu. Odstraňuje barvu/texturu, tj. materiál, a odhaluje geometrii (obrys objektu).

const geometry = new TorusGeometry(1, 0.2, 16, 16);
const material = new MeshBasicMaterial({});
const torus = new Mesh(geometry, material);

material.wireframe = true;

scene.add(torus);

Zde je návod, jak to vypadá:

Jak vidíte, existuje mnoho křižujících se čar. Toto jsou segmenty (trojúhelníky) tvaru.

Použijme tuto vlastnost v našem GUI pro ladění.

gui.add(material, 'wireframe');

gui.add() vezme objekt a wireframe je vlastnost, kterou chceme přepínat. gui.add() metoda může mít různé typy vlastností (druhý argument, který je třeba změnit). Můžeme použít funkce, booleany, čísla, rozsahy atd. Jedna věc, kterou je třeba poznamenat, je, že jsme se rozhodli změnit wireframe vlastnost, pokud zadáme něco jiného (například jdfkdfjkd místo wireframe ), nebude to fungovat.

Takto vypadá naše GUI:

Jak můžete vidět, štítkem pro vlastnost je vlastnost samotná (druhý argument jsme uvedli jako wireframe a to se také používá jako označení).

// Set the label to "Name1"
gui.add(material, 'wireframe').name('Name1');

Po změně našeho štítku vypadá naše GUI takto:

Závěr

Three JS je super zajímavý a myslím, že tohle by mohla být cesta, kterou se v budoucnu vydat! Děkuji, že jste dočetli až sem. Dále budu psát o animaci našich postav pomocí transformací, rotací atd. Zatím ahoj 🤟