3D modellek importálása three.js segítségével

3D modellek importálása three.js segítségével

Bemutatás

Mi az a three.js?

A Three.js egy fantasztikus, nyílt forráskódú 3D grafikai könyvtár, ami lehetővé teszi, hogy valós idejű 3D grafikákat hozzunk létre a böngészőben. Kezdetben 2010-ben indult, de azóta folyamatosan fejlődik egy nagy és lelkes közösség támogatásával. Ha még több részletre vagy kíváncsi, látogass el a Three.js GitHub repojára.

Lássunk is neki!

Kiinduló html oldal 

Először is, hozzunk létre egy alap HTML oldalt, ami a Three.js projektünk alapját képezi.

Hozzunk létre egy egyszerű jelentet

Végigvezetlek, hogyan tudsz egy nagyon egyszerű jelentet bele varázsolni a weboldaladba

  • Első lépésként beimportáljuk ezt a könyvtárat, hogy hozzáférhessünk az összes szükséges funkcióhoz.
  • Inicializáljuk a 3D teret és a kamerát. Gondolj a térre, mint egy virtuális világra, ahol minden objektum él. A kamera pedig olyan, mint egy fényképezőgép, amely ezt a világot nézi.
  • Hozzunk létre egy WebGL renderert, amely megjeleníti a 3D objektumokat a képernyőn. Ezt a renderert hozzáadjuk a HTML oldalhoz.
  • Készítsünk egy egyszerű 3D kockát, amit a térben elhelyezünk. A kocka három fő elemből áll: geometria, anyag és hálózat (mesh).
  • Végül definiálunk egy animációs függvényt, amely folyamatosan forgatja a kockát. Ez a függvény időzített ciklusokat használ, hogy megváltoztassa a kocka forgását, majd újra renderelje a jelenetet a kamerával.

Ha minden jól csináltunk, akkor egy olyan kocka fog megjelnni a képernyőnkön, amely forog. Sajnos ez így nem igazán izgi...

Bonyolítsuk a dolgokat!

Koncepció: Szeretnék létrehozni egy olyan weboldalt, ahol a szöveg középen helyzkedik el, és mondjuk kettő város model van a weboldal bal és a jobb szélén, körbeölelve a szöveget.

Erre létre is hoztam egy nagyon egyszerű kis rajzot, ami bemutatja hogyan gondoltam el az oldal felépítését:

A modelt a következő repóból tudjátok letölteni: https://github.com/mrdoob/three.js/blob/master/examples/models/gltf/LittlestTokyo.glb

Ez a model a LittlestTokyo névre hallgat, lowpoly stílusban egy japán városrész aminek a készítője Glen Fox - https://www.artstation.com/glenatron

Előkészületek

  • Generáljunk egy új projektet vite segítségével  a vite hivatalos dokumentációja szerint (https://vitejs.dev/guide/)
  • Készítsünk egy models, images mappát a src-ba (ezekben a mappákban fognak élni az asseteink, képek, modellek)
  • Hozzunk létre egy alap style.css fájlt és egy script.js-t
  • NPM segítségével telepítsük fel a Three.js-t 
    • npm install --save three

Hogyan nézzen ki az index.html? 

Mivel nagyon alap, kis egyszerű oldalról van szó, ezért itt alig lesz dolgunk!

  • Alap HTML struktúra
  • Hívjuk be a stíluslapunkat, készítsünk egy alapvető konténert ami tartalmazza a Lorem ipsum szöveget.
  • Készítsünk egy egyedi azonosítóval ellátot div-et (ebbe fogjuk belehívni a three-js jelentünket)
  • Majd importáljuk be a scriptünket type=“module”-ként

Hogyan nézzen ki a styles.css?

Ez a stíluslap egyszerűen igazítja középre a szöveget, beimportált fontot használ, és létrehoz egy abszolút pozicionált háttérképet a háttérnek, ami fix marad, ahogy görgetsz. Ezen kívül további egyedi stílusokat és formázásokat is hozzáadhatsz, amelyek megfelelnek az oldalad designjának.

 

Hogyan nézzen ki a script.js?

Elsőnek importáljuk a three.js és néhány addon könyvtár moduljait. Ezek a modulok segítenek a 3D jelenet létrehozásában és a modellek betöltésében.

  • A DRACOLoader egy hasznos kiegészítő, amely lehetővé teszi tömörített 3D modellfájlok problémamentes betöltését. Ezen fájlok használatával lenyűgöző és részletgazdag 3D modellek jeleníthetők meg a weboldalon.
  • A GLTFLoader egy másik kritikus elem a projektünkben, ami a 3D modellek beolvasásáért felelős. Segítségével könnyedén integrálhatjuk és kezelhetjük a kívánt 3D objektumokat a webes jelenetünkben.
  • A "container" egy HTML div elemre mutat, amely az oldalunkon található. Ez a div fogja majd befogadni és megjeleníteni a 3D jelenetet, amit létrehozunk.
  • A "renderer" egy kulcsfontosságú komponens, amely felelős a jelenetünk rendereléséért. Az "antialias" tulajdonság pedig az élsimítást aktiválja, ami a jelenetünk grafikai minőségét javítja.
  • A "scene" változó egy "Scene" objektumot hoz létre, amely a 3D jelenet alapját képezi. Itt kerülnek elhelyezésre és kezelésre a modellek, színek, fények és kamerák.
  • A "camera" változó a kamera objektumát reprezentálja, amelyen keresztül a jelenetet megjelenítjük. A "PerspectiveCamera" segítségével létrehozzuk a perspektívás nézetet, ami lehetővé teszi az objektumok távolságának és mélységének érzékeltetését.
  • Végül, de nem utolsósorban, a "PMREM generátor" egy komponens, amely a fényterjedést szimulálja a jelenetben, hozzájárulva ezzel a valósághűbb és életszerűbb megjelenítéshez.

 

Létrehozunk egy háttér textúrát, amely egy egyszerű PNG kép, és beállítjuk a háttérképünket, hogy teljesen bevonja a jelenet háttérét.

A jelenetnek beállítjuk a fényterjedését (environment), amely megvilágítja az objektumokat a jelenetben, létrehozva ezzel a megfelelő atmoszférát.

A kamera pozícióját az x, z és y tengelyek mentén beállítjuk az igények szerint.

Megadjuk a DRACO dekóder elérési útvonalát, amely lehetővé teszi a tömörített modellfájlok dekódolását.

A GLTF loader segítségével betöltjük a 3D modelleket, majd beállítjuk a méretüket, pozíciójukat és hozzárendeljük őket a jelenethez.

Ezt a folyamatot megismételjük egy második modell esetén is, hogy ugyanarra a modellre alkalmazzuk az előző lépéseket.

Végül, de nem utolsó sorban, létrehozzuk a "mixer" objektumot, és a modellhez rendelt animációt a "clipAction" függvény segítségével játszatjuk le. Ez lehetővé teszi az animáció szimulálását, és csak az egyik modell animálására korlátozódik jelenleg.

Az animation loop 

Az "requestAnimationFrame(animate)" sor a böngésző beépített "requestAnimationFrame" funkcióját alkalmazza az animációs ciklus létrehozására. Ennek a célja, hogy biztosítsa az animáció simaságát, és lehetővé tegye a böngésző számára, hogy a lehető legmagasabb képkockasebességgel futtassa az animációt.

Amennyiben rendelkezünk egy "mixer" objektummal, akkor az "update" metódust hívjuk meg a "clock.getDelta" függvénnyel, amely visszaadja az aktuális és az előző frissítés között eltelt időt másodpercben. Ez a lépés szükséges annak érdekében, hogy az animáció simán fusson.

Ha pedig van egy "mixer2" objektumunk, akkor azt a "y" tengely körül forgatjuk balra, egyenletes sebességgel.

Ezzel a részletezéssel túl vagyunk az oldalunk nagy részén, de még két rendkívül fontos lépés van hátra.

Oldal újraméretezés kezelése és görgetés

Ha újraméreteznénk az oldalt, sajnos azt tapasztalhatjuk, hogy a kamera, a háttér és az aspect ratio nem igazán követő a viewportot.

Ezt nagyon egyszerűen kezelhetjük:

Ezek az eseménykezelők beállítják a kamera aspektusát az ablak méretéhez, frissítik a kamera vetítési mátrixát, és beállítják a WebGL renderelő felület méretét az ablak méreteihez a méretezés eseményére. Emellett figyelik a görgetést, és a kapott görgetési mérték alapján módosítják a modell rotációját.

 

Végeredmény

Török Ádám

Török Ádám

Fejlesztő