Skip navigation

Pontfelhő geometria és anyag

Pontfelhő felépítése

Térbeli koordináta megadása

A legegyszerűbb geometria a térbeli pont, amit X, Y és Z koordinátáival tudunk megadni. A példánkban mindhárom koordináta véletlenszerűen kap értéket a [-1000, 1000] intervallumból (a kamera paramétereit ennek megfelelően állítjuk be). A koordináta értékeket egy vertices nevű JavaScript tömbhöz adjuk. A tömbhöz tetszőleges számú további koordináta hármast hozzáadhatunk további push() függvényhívásokkal.

let vertices = [];
vx = Math.random() * 2000 - 1000;
vy = Math.random() * 2000 - 1000;
vz = Math.random() * 2000 - 1000;
vertices.push( vx, vy, vz );

JavaScript tömb helyett közvetlenül Float32Array típusolt tömböt is létrehozhatunk és indexeléssel adhatunk értéket az elemeknek. Az alábbi példában 10000 darab csúcspontot hozunk létre véletlenszerű koordináta értékekkel. For ciklussal járjuk be a tömböt, figyelve az indexelés helysségére. A típusolt tömb létrehozásakor figyelni kell arra, hogy hány darab értékkel szeretnénk használni. Egy csúcsponthoz 3 koordináta érték tartozik, így 30000 darab float értékre lesz szükségünk. A korábban leírtak szerint érdemes külön változókat létrehoznunk az egyes egységek darabszámaira és azokat használni a kód megfelelő részén, hogy változás esetén csak egy helyen kelljen módosítani.

// Ponthalmaz
let particleCount = 10000;
let particlePositionAttributeSize = 3;

let vertices = new Float32Array( particleCount * particlePositionAttributeSize )
;
for( let i = 0, idx = 0; i < particleCount; i++, idx += particlePositionAttributeSize ) {
vertices[ idx ] = Math.random() * 2000 - 1000; // vx
vertices[ idx + 1 ] = Math.random() * 2000 - 1000; // vy
vertices[ idx + 2 ] = Math.random() * 2000 - 1000; // vz
}

Puffer attribútum tömb beállítása

A következő lépésben létrehozzuk a BufferGeometry objektumot és átadjuk pozíció attribútumként az előző lépésben létrehozott típusolt tömböt.

// Geometria létrehozása + attribútum beállítása
let particlesGeometry = new THREE.BufferGeometry();
particlesGeometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, particlePositionAttributeSize ) );

THREE.PointsMaterial

A ponthalmazok megjelenítését egy külön anyag, a PointsMaterial írja le. A konstruktornak egy paraméterhalmazt adhatunk át, de utólagosan is módosíthatjuk az attribútumokat a nevük segítségével.

color Pontok megjelenítési színe. Alapértelmezés a fehér (0xffffff) szín. Figyeljünk arra, hogy amennyiben a vertexColors true értékű, akkor egyrészt létre kell hoznunk egy szín tömböt a csúcspontokhoz, és a BufferGeometry objektumnak 'color' attribútumként be kell állítanunk. Másrészt az anyagnál megadott color értékkel a színértékeket komponensenként összeszorozza! Ha a tömbben beállított színeket szeretnénk látni, akkor figyeljünk arra, hogy a color a maximális fehér színű legyen.
size Pontok megjelenő mérete a raszteres képmátrixban. Alapérték 1.0.
sizeAttenuation Logikai érték, a kamerától való távolság befolyásolja-e a pont képernyőn megjelenő méretét?
Alapértelmezés a true.
vertexColors

A Three.js r114 verzió óta logikai érték. Alapértéke false (minden pont az anyaghoz beállított color attribútum színét kapja), true esetén minden ponthoz külön színt rendelhetünk, ami a geometria objektum color attribútumaként kell minden csúcsponthoz megadásra kerüljön.

Korábbi Three.js verziókban THREE.NoColors (alapértelmezés, minden pont az anyag color attribútum színét kapja), THREE.FaceColors, és THREE.VertexColors értékeket vehetett fel.

fog Ködhatás befolyásolja-e a pont színét? (A távolság növekedésével halványuljon-e a szín?)
map A pontok a színüket egy betöltött kép alapján kapják. Ezzel itt nem foglalkozunk.

Használati példa

let particlesMaterial = new THREE.PointsMaterial( { size: 2, color: 0xa0a000, sizeAttenuation: true } );

Minden ponthoz külön szín rendelése

04_01_c_ThreeJsPoints_VertexColors.html példaprogramban láthatunk konkrét példát, amit lentebb részletezünk.

Dokumentáció

Pontfelhő objektum

Az előkészített geometriából és anyagból hozhatjuk létre a pontfelhő objektumot, amit a színtérhez adhatunk.

particles = new THREE.Points( particlesGeometry, particlesMaterial );
scene.add( particles );

Dokumentáció

Megjegyzések

  • Korábbi Three.js verziókban a THREE.Points neve THREE.PointCloud, a THREE.PointsMaterial pedig THREE.PointCloudMaterial volt! A régi példaprogramok kódjában ezt módosítani kell.
  • Ha a pontfelhő objektum létrehozása után módosítunk a koordináta vagy szín adatokon, akkor azt jelezni kell a rendszernek a felszínháló objektum verticesNeedUpdate(), illetve colorsNeedUpdate() függvényhívásaival!

Egyszínű pontfelhő példaprogram

Részfeladatok

  • Létrehozunk egy 10.000 pontból álló felhőt, amely sárga színű pontokból fog állni.
  • A rendereléskor az X- és Y-tengelyek körül folyamatosan elforgatjuk.
  • Az egér mozgatásával a kamera pozícióját módosíthatjuk.
  • Megjelenítünk az origóban egy kék színű gömb drótvázat, ami szintén folyamatos forgást végez.

Teendők

  • Változtassuk a ponthalmaz számosságát!
  • Változtassuk a pont anyag paramétereit!

A 04_01_a_ThreeJsPoints_JS_array.html példaprogram JavaScript tömbök használatával oldja meg a feladatot. A 04_01_b_ThreeJsPoints_Float32Array.html példaprogramban közvetlenül Float32Array tömböt hozunk létre.

Pontfelhő pontonkénti színezése példaprogram

A pontfelhő egyenkénti színezését a 04_01_c_ThreeJsPoints_VertexColors.html példaprogramban láthatjuk. A kapcsolódó kódrész az alábbi.

// Ponthalmaz
let particleCount = 10000;
let particlePositionAttributeSize = 3; // X, Y, Z
let particleColorAttributeSize = 3; // R, G, B

let vertices = new Float32Array( particleCount * particlePositionAttributeSize );
let vertexColors = new Float32Array( particleCount * particleColorAttributeSize );
for( let i = 0, idx = 0; i < particleCount; i++, idx += 3 ) {

vertices[ idx ] = Math.random() * 2000 - 1000; // vx
vertices[ idx + 1 ] = Math.random() * 2000 - 1000; // vy
vertices[ idx + 2 ] = Math.random() * 2000 - 1000; // vz
vertexColors.set( [ Math.random(), Math.random(), Math.random() ], idx ); // R, G, B
}


// Geometria létrehozása + attribútumok beállítása
let particlesGeometry = new THREE.BufferGeometry();
particlesGeometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, particlePositionAttributeSize ) );
particlesGeometry.setAttribute( 'color', new THREE.BufferAttribute( vertexColors, particleColorAttributeSize ) );

let particlesMaterial = new THREE.PointsMaterial( { size: 2, color: 0xffffff, vertexColors: true, sizeAttenuation: true } );
particles = new THREE.Points( particlesGeometry, particlesMaterial );

scene.add( particles )
;

A vertexColors tömböt a Three.js implementációja Float32Array-ként várja, a színcsatornák intenzitását [0, 1] tartományban megadva. A szín tömböt 'color' attribútumként adjuk át. Figyelni kell arra, hogy az anyag objektumnál a vertexColors attribútum true értékű legyen, illetve a color attribútumát 0xffffff-re állítsuk. Próbáljuk ki, mi történik, ha más értéket adunk meg itt!