Skip navigation

Saját felszínháló létrehozása

Háromszögháló

3D objektumok felszínét háromszögekkel közelíthetjük. A háromszögek térbeli csúcspont koordinátáit ugyanúgy a geometria position attribútumaként adjuk meg, mint a pontfelhő és a vonalak esetén. Itt is lehetőségünk van csúcspontonkénti szín megadásra, emellett normálvektor és textúra koordináta attribútumot is használhatunk. Egy csúcspont újboli felhasználásához index tömböt is átadhatunk a geometriához.

Anyagként a korábban, a Three.js beépített objektumainál  megismertek használhatók (pl. MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial). Az utóbbi kettő csak akkor működik, ha normálvektorokat is megadunk a lapokhoz, ami a fény beesési szögének számításához elengedhetetlen. Ennek módját a következő fejezetben tárgyaljuk, jelenleg csak a megvilágítás nélküli esetet nézzük meg.

Felszínháló felépítése

Trapéz modellezése példa (különálló háromszögekből)

Példaként egy trapéz modellt készítünk, amit 3 darab különálló háromszögből építünk fel.

A megoldást a 04_04_a_ThreeJsTrapezium.html mutatja.

Hozzuk létre a csúcspont tömböt. Három háromszögünk van, egyenként 3 csúcsponttal, vagyis összesen 9 koordinátát adunk meg. Figyeljük meg, hogy  az 1, 2, 3 sorszámúak koordinátái többször is megadásra kerülnek, mert két háromszög megalkotásában is részt vesznek.

// Csúcspontok tömbje
let vertices = [];
vertices.push(

-5.0, 5.0, 0.0, // V0
-2.5, 0.0, 0.0, // V1
0.0, 5.0, 0.0, // V2
-2.5, 0.0, 0.0, // V1
2.5, 0.0, 0.0, // V3
0.0, 5.0, 0.0, // V2
0.0, 5.0, 0.0, // V2
2.5, 0.0, 0.0, // V3
5.0, 5.0, 0.0 // V4
)
;

Hozzuk létre a geometriát és adjuk hozzá a pozíció attribútum tömböt.

// Attribútumok beállítása
geometry = new THREE.BufferGeometry();
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) )
;

Szükség lesz egy anyagra is.

let material = new THREE.MeshBasicMaterial( { color: 0xffff00, wireframe: false } );

Ezután jöhet a háromszögháló létrehozása és színtérhez adása.

let poly = new THREE.Mesh( geometry, material );
scene.add( poly );

Megjegyzés

A trapézt természetesen két háromszögből is összerakhatjuk, pl. a (0, 1, 4), (1, 3, 4) csúcspontokból állókból, nincs feltétlenül szükség a 2 indexű csúcspontra. A példa szempontjából most számunkra jobb a három háromszöges megoldás.

Trapéz modellezés index tömb használattal (megosztott csúcspontokkal)

Az előző változatban néhány koordinátát többször is fel kellett sorolni. Az index tömb segítségével lehetőségünk van az egyszer már definiált csúcspontot újra felhasználni az alábbi módon (04_04_b_ThreeJsTrapezium_Indexed.html).

A csúcspont tömb itt csak 5 elemű, elegendő mindegyiket egyszer megadni.

// Csúcspontok tömbje
let vertices = [];
vertices.push(

-5.0, 5.0, 0.0, // V0
-2.5, 0.0, 0.0, // V1
0.0, 5.0, 0.0, // V2
2.5, 0.0, 0.0, // V3
5.0, 5.0, 0.0 // V4
);

Az előző tömb csúcspontjait indexelve adhatjuk meg a három darab háromszög lapot.

// Lapok index tömbje
let indices = [];
indices.push(

0, 1, 2, // Face 1
1, 3, 2, // Face 2
2, 3, 4 // Face 3
)
;

A geometria attribútum beállítások az alábbiak:

// Attribútumok beállítása
geometry = new THREE.BufferGeometry();
geometry.setIndex( new THREE.Uint16BufferAttribute( indices, 1 ) );
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) )
;

Az index értékeket 16 bites előjel nélküli egész számra alakítva adjuk át.

Az index tömb korlátja

Nagyon fontos megjegyezni, hogy a geometriához egyetlen index tömböt tudunk csak megadni, ami a csúcspont definícióhoz használt összes attribútum tömböt egyszerre indexeli. Arra nincs lehetőség, hogy a különböző attribútumok más-más indexszel rendelkezzenek!

Az a következőket jelenti:

  • A különféle attribútum tömbök elemszáma meg kell egyezzen! (Legalábbis amiket indexelünk belőlük.)
  • Ha egy térbeli koordináta más színnel, normálvektorral, textúra koordinátával is részt vesz a geometria megalkotásában, akkor muszáj többször felsorolnunk az összes szükséges kombinációban!

Síkidom előlap és hátlap

Az OpenGL/WebGL/Three.js modellezés kapcsán fontos megértenünk a síkidom előlapok és hátlapok koncepcióját.

Próbáljuk ki a következőket az előző példaprogram kapcsán.

  • Mozgassuk úgy a kamerát az egérrel, hogy a trapéz "túlsó" oldalát lássuk. A háromszögek el fognak tűnni!
  • Módosítsunk a lapok indexsorrendjén a forráskódban. Például a második lap esetén az (1, 3, 2) sorrendet cseréljük le a logikusabbnak látszó (1, 2, 3)-ra. Így a középső háromszög szemből nem jelenik meg, a túlsó oldalról viszont látszik, ahol a másik kettő nem!

A jelenség oka, hogy a modellezéskor alapértelmezésként a síkidomoknak csak az előlapja jelenik meg! Gondoljunk bele, ez logikus zárt felszínek (téglatest, gömb. stb. ) "kívülről"  történő megjelenítésekor, mivel a hátlapok biztosan nem látszanak a kamerából. Problémát jelent viszont nyílt felszínek, vagy sík geometriák esetén.

Hogyan adhatjuk meg, melyik legyen az előlap?

Ezt a lapok létrehozásakor a csúcspontok vagy az indexek sorrendje határozza meg. Az az előlap, amely esetén a kamerából nézve a csúcspontok megadási sorrendje ellentétes az óra járásával.

Hogyan jeleníthető meg mégis a hátlap is?

Az anyagnál a side attribútum értéket kell állítani, ahogyan korábban láttuk.

Feladat

Módosítsuk a trapéz modellezést úgy, hogy a két szélső háromszög vörös színű legyen, a középső maradjon sárga!

A vonalszakasz modellezésnél látott módon létre kell hozni egy szín tömböt és 'color' puffer attribútumként megadni a geometriának. Figyeljünk arra, hogy a szín puffer típusa csak Float32 lehet, és így a színek értékeit 0.0 és 1.0 közötti tört értékként kell megadnunk!

A felszínháló esetében is külön jelezni kell az anyag objektumban a csúcspontonkénti színmegadást (vertexColors: true), és figyelni arra, hogy az anyagnál megadott színértékkel elegyíteni fogja a csúcspont színeket a rendszer. Célszerű az alapértelmezett fehéren hagyni.

Írjuk át így mindkét trapéz modellező programot! Figyeljünk arra, hogy a szín tömb elemszáma megegyezzen a csúcspontok számával (9 és 5 darab legyen).

A megjelenés nagyon különböző! Az indexelt módszerrel nem is tudjuk ezt a feladatot érdemben megoldani. A probléma az, hogy az 1, 2 és 3 sorszámú csúcspontok vörös és sárga háromszögnek is részei, és csak egyféle szín rendelhető hozzájuk. A háromszögek belső területe pedig a csúcspontok színeinek interpoláltjaival töltödik fel. (A példában ezek a csúcspontok kaptak sárga színt, a 0 és 4 pedig vöröset.)

Különálló háromszögek esetén jó a színezés Indexelt csúcspontok esetén vörös-sárga színátmenetet látunk