WebGL met Three.js Shaders

3D-afbeeldingen in de browser zijn sinds de introductie ervan een aandachtspunt. Maar als u uw apps zou maken met behulp van gewone oude WebGL, zou dit eeuwen duren. Onlangs zijn enkele echt bruikbare bibliotheken beschikbaar gekomen. Three.js is een van de meest populaire en in deze serie laat ik je zien hoe je er het beste gebruik van kunt maken, om verbluffende 3D-ervaringen voor je gebruikers te creëren.

Ik verwacht dat je een basiskennis van 3D-ruimte hebt voordat je deze tutorial begint te lezen, omdat ik niet dingen als coördinaten, vectoren, enz. Zal uitleggen.


Een woord over Shaders

Als u al weet wat shaders zijn, kunt u deze stap overslaan. Shaders zijn in principe programma's die zijn geschreven in GLSL (Graphics Layer Scripting Language), die worden uitgevoerd op de GPU. Dit maakt ze bijzonder nuttig, omdat we wat werk van de CPU kunnen nemen en op de GPU kunnen zetten om de prestaties te verbeteren. Er zijn twee soorten: vertex en fragment shaders. Vertex shaders worden gebruikt om de structuur van het object aan te passen (verplaats de hoekpunten) en fragment shaders maken wijzigingen in de pixels die worden getekend.


Stap 1: Vertex Shader

We zullen beginnen met de eenvoudigere. Deze arcering wijzigt de plaatsing van de vectoren in het net, wat resulteert in bewegende vlakken. Voer deze code in van je app:

 

De type kenmerk van dit script wordt niet begrepen door de browser, dus het wordt niet uitgevoerd (we zullen de inhoud later doorgeven aan het materiaal Three.js). In de eerste twee regels definiëren we twee variabelen. De eerste is uniform zweeftijd. Uniformen worden doorgegeven aan zowel vertex als fragment shaders. Vervolgens is er variërend vec2 vUv. Variaties zijn de interface tussen de vertex en de fragmentshader. tijd houdt de tijd in milliseconden vast sinds de app is gestart, die we zullen gebruiken om nieuwe posities van hoekpunten te berekenen. In VUV we zullen de UV (textuurvector) van elke vertex opslaan, zodat we deze in de fragmentshader kunnen gebruiken.

Vervolgens is er de void main () verklaring. Alle shaders moeten deze functie hebben. Hierin passeren we de UV van de vertex naar onze VUV en het berekenen van de nieuwe positie van de vertex. Ten slotte hebben we de gl_Position, die in feite de positie van de top bepaalt. Maar ook, we moeten de positie vermenigvuldigen die eerder door de projectionMatrix en modelViewMatrix, twee matrices die Three.js ons levert. Dit is nodig, want als we dit niet doen, zal de GPU het punt niet beschouwen vanaf waar we naar het hoekpunt kijken. Laten we nu naar de fragmentshader gaan.


Stap 2: Fragment Shader

Dit is de plaats waar alle magie gebeurt. Fragment shaders zijn verantwoordelijk voor al die mooie games. Degene die we zullen gebruiken is vrij eenvoudig, dus verwacht geen scène van Crysis 3 te zien na het gebruik ervan. Voeg de volgende code toe onder uw hoekpunt-arcering:

 

Zoals u aan de bovenkant van de arcering kunt zien, zijn er opnieuw onze twee variabelen. U moet in gedachten houden dat alle variabelen die u gebruikt (behalve die uit Three.js) moeten worden gedefinieerd in elke shader die ze gebruiken in.

In de void main () functie, berekenen we de kleuren op basis van de tijd en UV van het fragment (fragmentschaduwen werken op fragmenten, die zijn samengesteld uit hoekpunten, dus de waarden van wisselende variabelen worden geïnterpoleerd in de fragmentshader). Voel je vrij om te knoeien met die getallen en functies (onthoud alleen dat de kleurwaarden positief moeten zijn).

Ten slotte stellen we de gl_FragColor variabele die de kleur van het fragment instelt.

Als u nu uw browser opent, verandert er niets, omdat we het materiaal van het object moeten veranderen, zodat het gebruik maakt van shaders.


Stap 3: THREE.ShaderMaterial

Dit speciale materiaal wordt gebruikt wanneer we shaders moeten gebruiken. Laten we het materiaal van het object wijzigen dat we in het vorige deel van deze serie aan ons model hebben toegevoegd. Definieer eerst de uniformen array die zal worden gebruikt om variabelen door te geven aan de shaders:

 var uniforms = tijd: type: "f", waarde: 0, resolutie: type: "v2", waarde: nieuw THREE.Vector2, textuur: type: "t", waarde: THREE.ImageUtils. loadTexture ('./ box.png');

Vervolgens, in de Loader.load definieer de itemhet materiaal en gebruik het:

 var itemMaterial = nieuw THREE.ShaderMaterial (uniforms: uniforms, vertexShader: document.getElementById ('cubeVertexShader'). innerHTML, fragmentShader: document.getElementById ('cubeFragmentShader'). innerHTML); item = nieuwe THREE.Mesh (nieuwe THREE.CubeGeometry (100, 10, 10), itemMaterial);

Als u nu de browser opent, ziet u dat de rode balk de kleuren heeft gewijzigd:


Maar de kleuren veranderen niet en de mesh is ook niet geanimeerd. Om dat te veranderen, moeten we het updaten tijd variabele in de shaders telkens wanneer een frame wordt getekend. Ga naar de geven functie en voeg deze regel toe na de clock.getDelta () bellen:

 uniforms.time.value + = delta * 10;

Als je nu de browser opent, zou je een mooi geanimeerd en kleurrijk object moeten zien:



Een woord over prestaties

Als we een dergelijk textuureffect zouden maken met behulp van bijvoorbeeld HTML5 Canvas, zou het proces teveel van de CPU-cycli in beslag nemen, wat resulteert in vertragingen. Maar alle shaders worden uitgevoerd op de GPU, die is geoptimaliseerd voor alle bewerkingen op afbeeldingen en die is gericht enkel en alleen op hen. Het scheiden van grafische en niet-grafische berekeningen is de sleutel tot een goed presterende app.

Als je iets echt wilt maken met WebGL, sta me toe je te verzekeren dat je zoveel mogelijk werk naar de GPU moet verplaatsen om je applicatie soepel en responsief te maken.


Conclusie

Zoals je kunt zien, stelt het gebruik van Three.js ons in staat om heel gemakkelijk 3D-afbeeldingen in de browser te maken, en de resultaten zijn eigenlijk best goed. Maar ze kunnen nog beter zijn, bekijk deze voorbeelden op de website van Three.js:

  • Hyperlapse
  • De TNT For Two

Met voldoende tijd, een creatieve geest en Three.js kun je ook geweldige apps maken. Ik zal meer dan blij zijn om je Three.js-creaties te zien. Bedankt voor het lezen.