La oss bygge en 3D-grafikkmotor poeng, vektorer og grunnleggende begreper

3D-spillmotorer som ligger bak dagens største spill, er svimlende arbeid med matematikk og programmering, og mange spillutviklere finner at forståelse av dem i sin helhet er en vanskelig oppgave. Hvis du mangler erfaring (eller en høyskole grad, som meg selv), blir denne oppgaven enda vanskeligere. I denne serien tar jeg sikte på å gå gjennom grunnleggende grafikksystemer i 3D-motorer.

Nærmere bestemt, i denne opplæringen vil vi diskutere poeng og vektorer, og alle de morsomme som følger med dem. Hvis du har en grunnleggende forståelse av algebra (variabler og variabel matte) og datalogi (grunnleggende om et objektorientert programmeringsspråk), bør du kunne gjøre det gjennom de fleste av disse opplæringsprogrammene, men hvis du har problemer med noen av konseptene, vær så snill å stille spørsmål! Noen av disse emnene kan være veldig vanskelig.

Du kan også få ekstra hjelp på Envato Studio, hvor du kan finne mange fantastiske 3D Design & Modeling-tjenester til rimelige priser. 

3D Design & Modeling-tjenester på Envato Studio

Grunnleggende om Koordinatsystemer

La oss starte med det grunnleggende. Tredimensjonal grafikk krever begrepet et tredimensjonalt rom. Den mest brukte av disse mellomrom kalles det kartesiske rom, som gir oss fordelene ved kartesiske koordinater (de grunnleggende \ ((x, y) \) notatene og 2D grid-spaced grafer som er undervist i de fleste høyskoler).


Avbildet: banen av mange high schoolers eksistens.

3-dimensjonalt kartesisk rom gir oss en x-, y- og z-akse (beskriver posisjon basert på horisontal plassering, vertikal plassering og dybde henholdsvis). Koordinatene for et hvilket som helst punkt i dette rommet vises som en tuppel (i dette tilfellet en 3-tuple, siden det er tre akser). På et 2-dimensjonalt plan kan en tuple avbildes som \ ((x, y) \), og i tredimensjonalt plan er det avbildet som \ ((x, y, z) \). Bruken av denne 3-tupelen er at den viser et punkts sted i forhold til romets opprinnelse (som i seg selv vanligvis vises som \ ((0,0,0) \)).

Tips: Tuple: en ordnet liste (eller sekvens) av elementer i datavitenskap eller matematikk. Så, \ ((K, y, l, e) \) ville være en 4-tuple, som viser en sekvens av tegn som utgjør mitt navn.

Innenfor dette rommet skal vi definere et punkt som en representasjon av en 3-tuple. Dette kan også vises som:

\ [P = (x, y, z) \]

I tillegg til denne definisjonen av et punkt må vi definere sine deler.

Hver av elementene i denne 3-tuplen er en skalar (tall) som definerer en posisjon langs a basisvektor. Hver basisvektor må ha en enhetslengde (det vil si en lengde på nøyaktig 1), slik at 3-tuples som \ ((1,1,1) \) og \ ((2,2,2) \) ikke kunne være grunnvektorer da de er for lange.

Vi definerer tre basisvektorer for vårt rom:

\ [\ Begynne innrettet
X & = (1,0,0) \\
Y & = (0,1,0) \\
Z & = (0,0,1)
\ End innrettet \]


Kilde: http://www.thefullwiki.org/Arithmetics/Cartesian_Coordinate.

Koordinatsystemet

La oss nå snakke om den matematiske definisjonen av vårt koordinatsystem, hvordan det påvirker vårt grafikksystem, og beregningene vi kan lage.

Representerer poeng

De opprinnelsespunkt av vårt koordinatsystem kan avbildes som punktet \ (O \), som representerer 3-tupelen (0,0,0). Dette betyr at den matematiske representasjonen av vårt koordinatsystem kan avbildes som:

\ [\ O, X, Y, Z \ \]

Med denne setningen kan du si at \ ((x, y, z) \) representerer et punkts posisjon i forhold til opprinnelsen. Denne definisjonen betyr også at ethvert punkt \ (P \), \ ((a, b, c) \) kan representeres som:

\ [P = O + aX + bY + cZ \]

Herfra skal jeg referere skalarer i små bokstaver og vektorer i store bokstaver - så \ (a \), \ (b \) og \ (c \) er skalarer, og \ (X \), \ Y \), og \ (Z \) er vektorer. (De er faktisk grunnvektorer som vi tidligere definerte.)

Dette betyr at et punkt hvis tuple er (2,3,4) kan representeres som:

\ [\ Begynne innrettet
(2,3,4) & = (2,0,0) + (0,3,0) + (0,0,4) \\
& = (0,0,0) + (2,0,0) + (0,3,0) + (0,0,4) \\
& = (0,0,0) + 2 (1,0,0) + 3 (0,1,0) + 4 (0,0,1) \\
& = O + 2X + 3Y + 4Z \\
\ End innrettet \]

Så, vi har tatt dette abstrakte konseptet om "et punkt i 3D-rom" og definert det som fire separate objekter lagt sammen. Denne typen definisjon er svært viktig når vi ønsker å sette noe konsept i kode.

Gjensidig vinkelrett

Koordinatsystemet som vi skal bruke, har også den verdifulle egenskapen å være gjensidig vinkelrett. Dette betyr at det er en 90 graders vinkel mellom hver av aksene hvor de møtes på sine respektive fly.


Vårt koordinatsystem vil også bli definert som "høyrehendt":

Kilde: http://viz.aset.psu.edu/gho/sem_notes/3d_fundamentals/html/3d_coordinates.html.

I matematiske termer betyr dette at:

\ [X = Y \ ganger Z \]

... hvor \ (\ times \) representerer kryssproduktoperatøren.

Hvis du ikke er sikker på hva et kryssprodukt er, kan det defineres av følgende ligning (forutsatt at du får to 3-tuples):

\ [(a, b, c) \ ganger (d, e, f) = (bf - ce, cd - av, ae - bd) \]

Disse uttalelsene kan virke kjedelige, men senere vil de tillate oss å gjøre en rekke forskjellige beregninger og transformasjoner mye lettere. Heldigvis behøver du ikke å huske alle disse ligningene når du bygger en spillmotor - du kan bare bygge ut disse setningene, og deretter bygge enda mindre kompliserte systemer på toppen av det. Vel, til du må redigere noe som er grunnleggende i motoren din, og må oppdatere deg selv på alt dette igjen!


Poeng og vektorer

Med alt grunnleggende i vårt koordinatsystem låst ned, er det tid til å snakke om poeng og vektorer, og enda viktigere, hvordan de samhandler med hverandre. Det første du må merke seg er at poeng og vektorer er tydelig forskjellige ting: et punkt er en fysisk plassering i ditt rom; en vektor er mellomrom mellom to punkter.


For å være sikker på at de to ikke blir forvirret, skriver jeg poeng i kursiv kursiv, som \ (P \), og vektorer i hovedfokus, som \ (\ mathbf V \).

Det er to hovedaksiomer som vi skal håndtere når vi bruker poeng og vektorer, og de er:

  • Axiom 1: Forskjellen mellom to punkter er en vektor, så \ (\ mathbf V = P - Q \)
  • Aksiom 2: Summen av et punkt og en vektor er et punkt, så \ (Q = P + \ mathbf V \)
Tips: en aksiom er et poeng med begrunnelse, ofte sett som tydelig nok til å bli akseptert uten argument.

Bygg motor

Med disse aksiomene oppgitt, har vi nå nok informasjon til å lage byggeklokklasser som ligger i hjertet av en hvilken som helst 3D-spillmotor: Punkt klasse og Vector klasse. Hvis vi skulle bygge vår egen motor ved hjelp av denne informasjonen, ville det være noen andre viktige skritt å ta når du lager disse klassene (for det meste å gjøre med optimalisering eller håndtering av eksisterende APIer), men vi skal forlate disse for Enkelhetens skyld.

Klasekseksjonene nedenfor kommer alle til å være i pseudokode, slik at du kan følge med ditt valg av programmeringsspråk. Her er skisser av våre to klasser:

Point Class Variables: num tuple [3]; // (x, y, z) Operatører: Point AddVectorToPoint (Vector); Punkt SubtraherVectorFromPoint (Vector); Vector SubtractPointFromPoint (punkt); Funksjon: // senere vil dette kalle en funksjon fra en grafikk-API, men for nå // dette bør bare skrive ut poengkoordinatene til skjermen drawPoint; 
Vector Class Variables: num tuple [3]; // (x, y, z) Operatører: Vector AddVectorToVector (Vector); Vector SubtractVectorFromVector (Vector); 

Som en øvelse, prøv å fylle ut hver av disse klassens funksjoner med arbeidskode (basert på hva vi har gått over så langt). Når du har fått alt det som er ferdig, sett det på prøve ved å lage dette eksempelprogrammet:

main var punkt1 = nytt punkt (1,2,1); var point2 = nytt punkt (0,4,4); var vektor1 = ny vektor (2,0,0); var vektor2; point1.drawPoint (); // skal vise (1,2,1) punkt2.drawPoint (); // skal vise (0,4,4) vector2 = point1.subtractPointFromPoint (punkt2); vector1 = vector1.addVectorToVector (vector2); point1.addVectorToPoint (Vektor1); point1.drawPoint (); // skal vise (4,0, -2) point2.subtractVectorFromPoint (vector2); point2.drawPoint (); // skal vise (-1,6,7)

Konklusjon

Du gjorde det til slutten! Det kan virke som en forferdelig masse matematikk for å bare lage to klasser - og det er definitivt. I de fleste tilfeller trenger du aldri å jobbe med et spill på dette nivået, men å ha en intim kjennskap til spillingen av spillmotoren din er likevel nyttig (hvis bare for selvtilfredsheten).

Hvis du trodde at dette var morsomt, så sørg for å sjekke ut min neste veiledning om grunnleggende grafikksystem: transformasjoner!

Selvfølgelig, når du har opprettet grafikkmotoren, må du legge til noe innhold, så vær så snill å sjekke ut det brede utvalget av spillverdier og 3D-modeller på Envato Market.