WebGL med Three.js Textures & Particles

Sedan introduktionen har 3D-grafik i webbläsaren varit ett populärt ämne. Men om du skulle skapa dina appar med vanlig gammal WebGL skulle det ta mycket lång tid. Men nu har vi några ganska användbara bibliotek som vi kan dra nytta av, som Three.js. Så i denna serie ska jag visa dig hur du skapar fantastiska 3D-upplevelser för webbläsaren.

Jag förväntar dig att du ska ha en grundläggande förståelse för 3D-rymden innan du börjar läsa den här handledningen, eftersom jag inte kommer att förklara saker som koordinater, vektorer etc.


Förberedelse

Vi börjar med koden från föregående del av denna serie. Ta även de tillgångar jag gav och lägg dem i samma mapp som din app. Nu, eftersom vi kommer att använda bilder här måste du lägga din app på en statisk server (kan vara lokal), förutom om du startar webbläsaren med aktiverad filåtkomst från filer (till exempel med hjälp av --allow-file-access-from-filer flagga i Chrome) CORS låter dig inte ladda dem från filen. Det är allt du behöver göra innan du fortsätter.


Steg 1: Fylla på texturen

Om du någonsin blev så uttråkad att du gick med att skapa något med ren OpenGL, kommer du säkert ihåg hur mycket det är att ladda en textur. Lyckligtvis kommer Three.js med en bra funktion som laddar och sätter upp texturen för oss. Lägg till den här raden innan definitionen av kubens material är:

 var cubeTexture = THREE.ImageUtils.loadTexture ('./box.png');

Det är verkligen allt du behöver göra för att få din textur laddad.

I en verklig app skulle du behöva förinställa texturen som någon normal bild och visa användarna några fina laddningsfält för att låta dem veta att du laddar (Three.js kommer att använda den cachade bilden då).


Steg 2: Måla kuben

Nu ska vi applicera texturen på vår kub. Det här är också enkelt, du behöver bara byta färgdefinitionen i kubens material för att se så här ut:

 var cubeMaterial = nytt THREE.MeshLambertMaterial (map: cubeTexture);

De Karta attribut sätter texturen. Nu kan du öppna webbläsaren och du ska se en roterande texturerad kub:


Du kan också färga texturen, lägg bara till Färg definition i materialets alternativ, så här:

 var cubeMaterial = nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0x28c0ec);

Och nu blir kuben blå:


På så sätt kan du ha flera olika objekt med samma textur om bara färgen ändras.


Steg 3: Flera material

Du kan ställa in olika material för varje kubans ansikte. För att uppnå det måste du ändra hela materialets definition. Först definiera material array. Varje element i matrisen kommer att motsvara materialet i ett ansikte. De går i denna ordning: höger, vänster, topp, botten, fram och bak:

 var material = []; materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0xff0000)); // right face materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0xffff00)); // vänster ansikte materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, color: 0xffffff)); // top face materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0x00ffff)); // bottom face materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0x0000ff)); // front face materials.push (nytt THREE.MeshLambertMaterial (map: cubeTexture, färg: 0xff00ff)); // tillbaka ansikte

Som du kan se har varje ansikte sitt eget material, så du kan ställa in olika texturer, färger och andra attribut för var och en. Ändra sedan kubens material till THREE.MeshFaceMaterial:

 var cubeMaterial = nytt THREE.MeshFaceMaterial (material);

Du behöver bara passera material array som parameter. I webbläsaren ska du se att varje sida av kuben har olika färg:



Steg 4: Partiklar!

Låt oss säga att du vill skapa en effekt av snurrande snöflingor i din app. Om du skulle göra varje snöflinga som ett nät får du mycket låga fps. Det är där partiklar kommer i spel. De är långt mindre komplicerade, och att dra dem som ett helt partikelsystem gör dem väldigt effektiva.

Börja med att skapa en geometri för våra partiklar:

 varpartiklar = nya THREE.Geometry;

THREE.Geometry är ett grundgeometriobjekt, utan någon form. Nu måste vi definiera positionen för varje partikel i systemet. Låt det vara helt slumpmässigt:

 för (var p = 0; s < 2000; p++)  var particle = new THREE.Vector3(Math.random() * 500 - 250, Math.random() * 500 - 250, Math.random() * 500 - 250); particles.vertices.push(particle); 

Denna slinga skapar 2000 slumpmässigt placerade partiklar och sätter dem alla i geometrin. Därefter måste du definiera partiklarnas material:

 var particleMaterial = nytt THREE.ParticleBasicMaterial (färg: 0xeeeeee, storlek: 2);

Observera att vi använder THREE.ParticleBasicMaterial, som endast är för partiklar. I alternativen definierar vi bara färgen och storleken på varje partikel. Slutligen kan du skapa partikelsystemet och lägga till det på scenen:

 var particleSystem = nytt THREE.ParticleSystem (partiklar, partikelmaterial); scene.add (particleSystem);

Nu, för att få scenen att se bättre ut, låt vi rotera partiklarna i riktning motsatt den som kuben roterar in (byt ut göra funktion för att se ut så här):

 funktion render () requestAnimationFrame (render); var delta = clock.getDelta (); cube.rotation.y - = delta; partikelSystem.rotation.y + = delta; renderer.render (scen, kamera); 

Vi flyttade clock.getDelta till variabeln, för om du skulle använda det så:

 cube.rotation.y - = clock.getDelta (); particleSystem.rotation.y + = clock.getDelta ();

Partikelsystemet skulle inte rotera, eftersom det andra samtalet kommer att returnera ett tal nära noll (kom ihåg att det tar tid från det senaste samtalet).

Öppna nu webbläsaren och du bör se en kub och partiklar roterar:


Låt oss kombinera båda sakerna du har lärt dig i denna handledning och vrid de fula vita rutorna till riktiga snöflingor. Först, ladda snöflingan konsistens:

 var particleTexture = THREE.ImageUtils.loadTexture ('./ snowflake.png');

Byt nu partiklarnas material för att använda texturen. Aktivera även genomskinlighet och gör partiklarna större så att vi kan se formen:

 var particleMaterial = nytt THREE.ParticleBasicMaterial (map: particleTexture, transparent: true, size: 5);

Om du öppnar webbläsaren bör du se några fina snöflingor som flyter runt kuben:



Steg 5: Rök

Rökverkan är ganska lätt att uppnå och det ser bra ut. Börja med att skapa geometri, precis som med snöflingorna:

 var smokeParticles = new THREE.Geometry; för (var i = 0; i < 300; i++)  var particle = new THREE.Vector3(Math.random() * 32 - 16, Math.random() * 230, Math.random() * 32 - 16); smokeParticles.vertices.push(particle); 

Den enda skillnaden här är att vi väljer positionen från ett rektangulärt prisma med dimensioner 32x32x230. Låt oss nu ladda texturen och definiera materialet:

 var smokeTexture = THREE.ImageUtils.loadTexture ('./ smoke.png'); var smokeMaterial = nytt THREE.ParticleBasicMaterial (map: smokeTexture, transparent: true, mixing: THREE.AdditiveBlending, storlek: 50, färg: 0x111111);

I materiell definition finns det a blandning alternativ. Den berättar hur den ska göra ett objekt på en annan. Med THREE.AdditiveBlending Överlappande färgvärden kommer att sättas till varandra vilket kommer att resultera i en ljusare rök i de områden med högre partikeldensitet. Vi ställer också färgen till nästan svart, så röken ser naturligare ut.

Slutligen skapa partikelsystemet, flytta det lite till vänster och lägg till det på scenen:

 var smoke = nytt THREE.ParticleSystem (smokeParticles, smokeMaterial); smoke.sortParticles = true; smoke.position.x = -150; scene.add (rök);

Du måste också ställa in smoke.sortParticles till sant. När det är felaktigt kan spriteens bakgrund dras som svart. Om du öppnar webbläsaren bör du se en stillastående rökruta bredvid kuben:


För att animera röken måste vi gå igenom alla partiklarna och flytta upp dem lite. Lägg till den här koden i göra fungera:

 var particleCount = smokeParticles.vertices.length; medan (partikelCount--) var partikel = smokeParticles.vertices [particleCount]; partikel.y + = delta * 50; om (partikel.y> = 230) particle.y = Math.random () * 16; partikel.x = Math.random () * 32 - 16; particle.z = Math.random () * 32 - 16;  smokeParticles .__ dirtyVertices = true;

I slingan lägger vi till delta * 50 till y-positionen för partikeln. Därefter kontrollerar vi om partikeln är högre än 230, om så väljer vi slumpmässigt sin nya position någonstans i botten av rökstången. Slutligen, det viktigaste: att ställa in geometrin __dirtyVertices flagga till sant.

För att förbättra prestanda caching tre.js objekten för att undvika att bygga alla WebGL-samtal igen varje ram, så om vi ändrar något i objektets geometri måste vi låta renderaren veta att den har ändrats. I grund och botten __dirtyVertices flaggan kommer bara att nå elementet.

Om du öppnar webbläsaren bör du se en smidig animerad rök bredvid kuben.


Slutsats

I denna handledning har du lärt dig hur du använder texturer och partiklar. Som tidigare, var inte rädd för att experimentera lite med din app. Om du har problem ta en titt på dokumentationen. I nästa artikel lär jag dig hur man laddar modeller och animerar dem.