WebGL cu Three.js Shadere

Grafica 3D în browser a fost un subiect de interes de la introducerea sa. Dar dacă v-ați crea aplicațiile folosind WebGL obișnuit, ar dura vechime. Recent, au fost disponibile câteva biblioteci cu adevărat utile. Three.js este unul dintre cele mai populare și în această serie vă voi arăta cum să faceți cea mai bună utilizare a acesteia, pentru a crea experiențe 3D uimitoare pentru utilizatorii dvs..

Mă aștept să aveți o înțelegere de bază a spațiului 3D înainte de a începe să citiți acest tutorial, deoarece nu voi explica lucruri precum coordonate, vectori etc..


Un cuvânt despre Shaders

Dacă știți deja ce shadere sunt, puteți trece peste acest pas. Shaderele sunt în principiu programe scrise în GLSL (Graphics Layer Scripting Language), care sunt executate pe GPU. Acest lucru le face extrem de utile, deoarece putem prelua ceva de la CPU și îl putem pune pe GPU pentru a crește performanța. Există două tipuri: shader-uri de vârfuri și fragmente. Vitezele de vârf sunt folosite pentru a modifica structura obiectului (mutați vârfurile), iar shaderele de fragmente fac modificări la pixelii care sunt desenați.


Pasul 1: Vertex Shader

Vom începe cu cea mai simplă. Acest shader va modifica plasarea vectorilor în plasă, ducând la mutarea fețelor. Introduceți acest cod în din aplicația dvs.:

 

tip atributul acestui script nu va fi înțeles de browser, deci nu va fi executat (vom trece conținutul său la materialul Three.js mai târziu). În primele două rânduri definim două variabile. Primul este uniform timpul plutitor. Uniformele sunt transmise atât șuturilor de vârf, cât și celor de fragmentare. Apoi, există variații vec2 vUv. Variantele sunt interfața dintre vârful și shaderul fragmentului. timp va menține timpul în milisecunde de la pornirea aplicației, pe care o vom folosi pentru a calcula noi poziții de vârfuri. În VUV vom stoca UV-ul (vectorul de textură) al fiecărui vârf, astfel încât să îl putem folosi în fragmentul de shader.

Apoi, există void main () declaraţie. Toate shaderele trebuie să aibă această funcție. Aici trecem UV-ul vârfului către noi VUV și calculând noua poziție a vârfului. În cele din urmă, am setat gl_Position, care, de fapt, stabilește poziția vârfului. Dar, de asemenea, trebuie să înmulțim poziția calculată anterior de către projectionMatrix și modelViewMatrix, două matrice pe care Three.js ni le furnizează. Acest lucru este necesar deoarece, dacă nu facem acest lucru, GPU nu va lua în considerare punctul din care ne uităm la vârf. Acum hai să ne mutăm la shaderul fragmentului.


Pasul 2: Fragment Shader

Acum, acesta este locul unde se întâmplă toată magia. Fragmentele de shadere sunt responsabile pentru toate aceste jocuri bune. Cel pe care îl vom folosi este destul de simplu, așa că nu vă așteptați să vedeți o scenă din Crysis 3 după ce ați folosit. Introduceți următorul cod sub shaderul vârfului:

 

După cum puteți vedea în partea de sus a shader, există din nou cele două variabile. Trebuie să rețineți că toate variabilele pe care le utilizați (cu excepția celor de la Three.js) trebuie să fie definite în fiecare shader în care sunt folosite.

În void main () , calculăm culorile pe baza timpului și a UV-ului fragmentului (shaderele de fragmente funcționează pe fragmente, care sunt compuse din noduri, astfel încât valorile variabil variabilele sunt interpolate în fragmentul de shader). Simțiți-vă liber să mizerie cu numere și funcții (amintiți-vă doar că valorile de culoare trebuie să fie pozitive).

În cele din urmă, noi stabilim gl_FragColor variabilă care stabilește culoarea fragmentului.

Dacă deschideți acum browserul dvs., nimic nu se va schimba, deoarece trebuie să schimbăm materialul obiectului, astfel încât acesta să utilizeze umbrele.


Pasul 3: Materialul THREE.Shader

Acest material special este folosit ori de câte ori trebuie să folosim shadere. Să schimbăm materialul obiectului pe care l-am atașat modelului nostru în partea anterioară a acestei serii. Mai întâi, definiți uniforme array care va fi folosit pentru a trece variabilele la shadere:

 var / uniforme = timp: type: "f", valoare: 0, rezolutie: type: "v2", valoare: new THREE.Vector2, textura: type: "t"; loadTexture ('./ box.png');

Apoi, în loader.load defineste articolși folosiți-l:

 var itemMaterial = nou material THREE.ShaderMaterial (uniforme: uniforme, vertexShader: document.getElementById ('cubeVertexShader') innerHTML, fragmentShader: document.getElementById ('cubeFragmentShader'). item = nou TRE.Mesh (nouă TEGie.Celometrie (100, 10, 10), itemMaterial);

Acum, dacă deschideți browserul, ar trebui să vedeți că fascicolul roșu și-a schimbat culorile:


Dar culorile nu se schimbă și nici plasa nu este animată. Pentru a schimba acest lucru, trebuie să actualizăm timp variabilă în shaders de fiecare dată când este tras un cadru. Mergeți la face și adăugați această linie după clock.getDelta () apel:

 uniforms.time.value + = delta * 10;

Acum, dacă deschideți browserul, ar trebui să vedeți un obiect frumos animat și colorat:



Un cuvânt despre performanță

Dacă am fi creat un astfel de efect de textura folosind, de exemplu, HTML5 Canvas, procesul ar lua prea mult din ciclurile CPU-ului, ducând la întârzieri. Dar toate shaderele sunt executate pe GPU, care este optimizat pentru toate operațiile pe grafică și este focalizat numai pe ei. Separarea calculelor grafice și non-grafice este cheia unei aplicații de bună performanță.

Dacă doriți să creați ceva real folosind WebGL, permiteți-mi să vă asigur că va trebui să mutați cât mai multă lucrare pe GPU pentru a face aplicația să fie netedă și receptivă.


Concluzie

După cum puteți vedea, folosirea programului Three.js ne permite să realizăm foarte ușor grafica 3D în browser, iar rezultatele sunt de fapt destul de bune. Dar, ei pot fi chiar mai buni, aruncați o privire la aceste exemple din site-ul lui Three.js:

  • Hyperlapse
  • TNT pentru două

Cu suficient timp, o minte creativă și Three.js, puteți crea aplicații uimitoare, ca și acestea. Voi fi mai mult decât bucuros să văd creațiile voastre Three.js. Vă mulțumim pentru lectură.

Cod