WebGL Med Three.js Modeller og Animasjon

3D-grafikk i nettleseren har vært et varmt emne siden de ble introdusert. Men hvis du skulle lage appene dine ved å bruke vanlig gammel WebGL, ville det ta aldre. Det er derfor noen virkelig nyttige biblioteker har kommet. Three.js er en av de mest populære av dem, og i denne serien vil jeg vise deg hvordan du får det beste ut av det for å skape fantastiske 3D-opplevelser for brukerne dine.

Jeg forventer at du skal ha en grunnleggende forståelse av 3D-plass før du begynner å lese denne opplæringen, da jeg ikke vil forklare emner som koordinater og vektorer.


Forberedelse

Som vanlig starter vi fra koden du opprettet tidligere. Last ned og pakk ut de eiendelene jeg har gitt, og du vil være klar til å gå.


Trinn 1: Et ord om eksportmodeller i blender

Før vi starter programmeringsdelen, vil jeg forklare noe som mange mennesker har problemer med. Når du har en modell opprettet i Blender, og du vil eksportere den til Three.js-format, bør du huske følgende:

  • Først fjern foreldringen. Exportøren Three.js vil ikke eksportere noen animasjoner hvis du forlater den (dette gjelder også Armature Modifier)
  • For det andre, gruppepunkter. Hvis du vil at beinet skal bevege noen hjørner, må du gruppere dem, og navnet på gruppen med navnet på beinet.
  • For det tredje kan du bare ha en animasjon. Dette kan høres ut som et stort problem, men jeg vil forklare løsningen senere.

Når du eksporterer, må du også kontrollere at disse alternativene er valgt i eksportøren: Skinning, Bones og Skjelett Animasjon.


Trinn 2: Importere modellen

Som med stort sett alt i Three.js, er det veldig enkelt å importere modeller. Det er en spesiell klasse, THREE.JSONLoader det vil gjøre alt for oss. Selvfølgelig laster det bare JSON-modeller, men det anbefales å bruke dem så jeg vil bare dekke denne lasteren (andre jobber ganske mye på samme måte). La oss initialisere det først:

 var loader = ny THREE.JSONLoader; var animasjon;

Ingen argumenter nødvendig. Vi må også definere en variabel for animasjon, så vi kan få tilgang til det senere. Nå kan vi laste modellen:

 loader.load ('./ model.js', funksjon (geometri, materialer) var skinnedMesh = nytt THREE.SkinnedMesh (geometri, nytt THREE.MeshFaceMaterial (materials)); skinnedMesh.position.y = 50; skinnedMesh.scale. sett (15, 15, 15); scene.add (skinnedMesh); animere (skinnedMesh););

De laste Metoden aksepterer to parametre: En bane til modellen og en tilbakeringingsfunksjon. Denne funksjonen vil bli kalt når modellen er lastet (så i mellomtiden kan du vise en lastelinje til brukeren). En tilbakeringingsfunksjon vil bli kalt med to parametre: geometri av modellen og dens materialer (disse eksporteres med den). I tilbakekallingen lager vi nettverket, men denne gangen er det THREE.SkinnedMesh, som støtter animasjoner.

Deretter flytter vi modellen 50 enheter opp for å sette den på toppen av kuben, skala den 15 ganger (fordi jeg pleier å lage små modeller i Blender) og legge den til scenen. Neste kaller vi animere funksjon som vil sette opp og spille animasjonen.


Trinn 3: Animasjon

Nå setter vi opp animasjonen. Dette er kilden til animere funksjon:

 funksjon animere (skinnedMesh) var materials = skinnedMesh.material.materials; for (var k i materialer) materialer [k] .skinning = true;  THREE.AnimationHandler.add (skinnedMesh.geometry.animation); animasjon = ny THREE.Animation (skinnedMesh, "ArmatureAction", THREE.AnimationHandler.CATMULLROM); animation.play (); 

Først må vi aktivere skinning (animasjoner) i alle materialene i modellen. Deretter må vi legge til animasjonen fra modell til THREE.AnimationHandler og opprett THREE.Animation gjenstand. Parametrene er i følgende rekkefølge: masken for å animere, animasjonsnavnet i modellen og interpoleringstypen (nyttig når du har en komplisert modell som en menneskekropp, hvor du vil at nettverket skal bøyes jevnt). Til slutt spiller vi animasjonen.

Men hvis du åpner nettleseren nå, ser du at modellen ikke beveger seg:

For å fikse dette må vi legge til en linje til vår gjengi funksjon, like under particleSystem rotasjon:

 hvis (animasjon) animasjon.update (delta);

Dette vil oppdatere tiden på animasjonen, så THREE.AnimationHandler vet hvilken ramme som skal gjengis. Nå åpner du nettleseren, og du bør se toppkubens bøyning til venstre og til høyre:


Trinn 4: Flere animasjoner

Ja, det er en løsning for bare en animasjonssekvens i en modell, men det krever at du redigerer det. Tanken er at du legger til hver animasjon til en sekvens, da når den ene ender, begynner den neste. Etter at du har eksportert modellen din, må du endre animasjonskoden. La oss si at vi har en stående animasjon fra begynnelsen til tredje sekund, og en vandrende animasjon fra tredje sekund til slutt. Så i vår gjengi funksjon vi må sjekke hvilket sekund animasjonen er, og hvis den når slutten av den nåværende sekvensen, stopper den og spiller den fra begynnelsen:

 var currentSequence = 'standing'; funksjon (gjengiv) ... hvis (animasjon) animasjon.update (delta); hvis (currentSequence == 'standing') if (animation.currentTime> 4) animation.stop (); animasjon.spill (false, 0); // spille animasjonen ikke looped, fra 0s annet hvis (currentSequence == 'walking') if (animation.currentTime <= 4 || animation.currentTime > 8) animation.stop (); animasjon.spill (falsk, 4); // spille animasjonen ikke looped, fra 4s ...

Du må huske å starte animasjonene som ikke er sløyfet og fra riktig tid. Dette vil selvfølgelig være buggy hvis brukerens rammeprofil er veldig lav, fordi deltaet blir høyere og animation.currentTime kan være mye høyere enn grensen for en bestemt sekvens, noe som resulterer i å spille en del av den neste sekvensen. Men det vil bare være merkbart hvis deltasene er omtrent 300-500ms.

Nå for å endre animere fungere for å spille gangav animasjon, bare legg til disse argumentene til animation.play funksjon:

 animasjon.spill (false, 0);

La oss også la brukeren bytte mellom animasjoner ved hjelp av en nøkkel. Legg til denne koden på slutten av filen, like før render () anrop:

 document.addEventListener ('keyup', funksjon (e) if (e.keyCode == 'A'.charCodeAt (0)) currentSequence = (currentSequence ==' stående '?' walking ':' standing '); );

Trinn 5: Fest til ben

Denne teknikken er spesielt nyttig i RPG, men det kan også gjelde for andre sjangere. Det involverer feste et annet objekt til beinet i det animerte objektet: klær, våpen osv.

La oss begynne med å endre vår loader.load Ring tilbake. Legg til denne koden under scene.add (skinnedMesh '):

 item = new THREE.Mesh (new THREE.CubeGeometry (100, 10, 10), nytt THREE.MeshBasicMaterial (color: 0xff0000)); item.position.x = 50; pivot = nytt THREE.Object3D (); pivot.scale.set (0,15, 0,15, 0,15); pivot.add (pos); pivot.useQuaternion = true; skinnedMesh.add (pivot);

De punkt mesh simulerer noe du kanskje vil legge ved et animert objekt. For å få det til å rotere rundt et bestemt punkt, og ikke rundt sentrum, legger vi det til a dreie objekt og flytte det 50 enheter (halvparten av bredden) til høyre. Vi må skala den til 0,15, fordi det vil bli lagt til i skinnedMesh som har en skala av 15. Til slutt, før det legges til vårt animerte objekt, forteller vi det å bruke quaternions.

I utgangspunktet er quaternions et talesystem, men siden Three.js håndterer alt for oss, trenger du ikke å dykke inn i dette emnet hvis du ikke vil (men hvis du gjør det, ta en titt på Wikipedia-siden). De er vant til å rotere gjenstander uten risiko for gimbal lås.

Nå, i gjengi funksjon vi må oppdatere objektets posisjon og rotasjon:

 pivot.position = nytt THREE.Vector3 (). getPositionFromMatrix (skinnedMesh.bones [2] .skinMatrix); pivot.quaternion.setFromRotationMatrix (skinnedMesh.bones [2] .skinMatrix);

La meg forklare hva som skjer her. Først setter vi stillingen til å være den samme som på det siste benet i modellen. Vi bruker skinMatrix eiendom for å beregne det. Da bruker vi den samme egenskapen til å beregne kvaternionen for dreies rotasjon. Deretter kan du åpne nettleseren, og du bør se den røde strålen som er festet til vår modell:


Konklusjon

Jeg håper du har lært noen nye, interessante teknikker fra denne opplæringen. Som alltid, vær så snill å eksperimentere med appen som vi har opprettet. I den neste (og siste) opplæringen i denne serien, viser jeg deg den virkelige kraften til OpenGL / WebGL-Shaders.