Table of Contents
Perustukset: Edustaa kolmen eri välilyöntien
Ennen kuin yksi pikseli on tehty, 3D-moottorilla on oltava matemaattinen kieli kuvaamaan esineitä avaruudessa. Ydin on []vektorit[] (kolmekomponenttiset tuplet edustavat sijaintia, suuntaa tai väriä) ja [-matriisit[ (4×4 matriisit, jotka koodaavat muunnoksia). C, nämä määritellään tyypillisesti yksinkertaisiksi rakennelmiksi:
- pisteille ja vektoreille.
- sarakkeessa suuressa järjestyksessä tallennettujen muunnosmatriisien osalta.
Jokainen objekti koostuu -triangles]. Kolmio on määritelty kolme vertices, joista jokaisella on asema, ja valinnainen normaali ja väri. Säilyttäminen nämä toisiinsa liittyvät rakenteet (esim., varten kuutio) parantaa välimuistin tehokkuutta.
Grafiikkaputki: Vertikeista Pikseleisiin
Graafinen putkisto on vaiheiden sarja, joka muuntaa 3D kohtaustiedot 2D-kuvaksi. Perusohjelmistojen käännöksissä olevassa moottorissa otat manuaalisesti käyttöön jokaisen vaiheen. Päävaiheet ovat:
- Vertex Processing[ .
- Rasterit ... ..........................................................................................................................................................................................................................................
- Shading . ... ........................................................................................................................................................................................................................................
- Output Merging ... .......................................................................................................................................................................................................................................
Laitteistoa kiihdyttävät moottorit (käyttäen OpenGL:ää, Vulkania tai DirectX:ää) suorittavat suurimman osan näistä vaiheista GPU:ssa, mutta ohjelmistopolun ymmärtäminen antaa sinulle syvän käsityksen siitä, miten GPU toimii konepellin alla.
Vertex-käsittely ja -muunnos
Jokainen huippupiste alkaa -malliavaruudessa[ (paikalliset koordinaatit suhteessa kohteeseen). Asennat sen maailmassa, käytät [mallimatriisia[], joka koodaa käännöksen, pyörimisen ja skaalauksen. Sitten [-näyttömatriisi[ muuttaa maailman koordinaatit kamerasuhteellisiksi koordinaateiksi (näkymätila). Lopuksi -projektimatriisi[ karttojen mukaan näkymätila normalisoituun koordinaattijärjestelmään ([]-plip-tilaan[[]) ]), jossa perspektiivijako ja näkökentän kartoitus tuottavat näytön koordinaatteja.
C:ssä muunnostoiminnot näyttävät:
- . Palauttaa henkilöllisyytensä.
- ...] rakentaa käännösmatriisin.
- ... ....................................................................................................................................................................................................................................................
- . ... ..................................................................................................................................................................................................................................................
Vertex shader ekvivalentin ohjelmisto iteraatiot yli kaikki vertices, moninkertaistaa kunkin yhdistetty matriisi, ja tallentaa tuloksen muunnetun huippupistepuskuri.
Ennuste: Perspektiivi vastaan Orthographic
Projektion avulla ohjataan, kuinka syvyys on edustettuna näytöllä. [ Näkökulmaprojektio[ tekee etäisistä kohteista näyttävän pienemmän, luoden realismia. Sen matriisi on rakennettu näkökentästä, kuvasuhde, lähellä ja kaukana leikkelytasoissa. Klassinen kaava sisältää x- ja y-komponentteja z:llä (matriisin moninkertaistumisen jälkeen). C:ssä lasketaan projektiomatriisi kerran ja käytetään sitä uudelleen jokaisessa ruudussa:
- . Palauttaa vakioperspektiivimatriisin.
Ortografinen projektio[ säilyttää rinnakkaiset viivat ja on yksinkertaisempi, käytetään käyttöliittymän tai CAD-työkaluja. Se ei sisällä perspektiivin jakoa.
Rasterisaatio: Täyttökolmiot
Projektin jälkeen sinulla on 2D-ruudun koordinaatit (kuten pikselien sijainnit) ja syvyysarvo (z). Rasterisaatio rikkoo jokaisen kolmion kappaleiksi, jotka kattavat kokonaislukupikselikoordinaatit. Klassinen algoritmi on []skannauksen muuntaminen[:
- Järjestä kolmio... kolme vertices by y-koordinaatti.
- Kävele vasemmalle ja oikealle reunat, computing x rajat kunkin scanline.
- Laske kunkin pikselin vaakasuunnassa olevan spin-pisteen fragmenttien syvyys interpoloimalla kolmion poikki.
- Suorita -syvyystesti: vertaa fragmenttia . z-arvoon, joka on jo syvyyspuskurissa. Jos se on lähempänä, päivitä syvyyspuskuri ja laske fragmenttien väri.
Reunakävelyalgoritmin tehokas käyttöönotto C:ssä edellyttää tiukkaa silmukoiden käyttöä ja kiinteän pisteen aritmeettista huolellista käyttöä kelluvan pisteen yläpuolella. Monet harrastusmoottorit alkavat raakavoimalla (tarkistavat kaikki pikselit rajauslaatikossa) ja optimoivat myöhemmin reunayhtälöillä.
Varjostus ja valaistus
Yksinkertainen tasavarjostettu moottori käyttää yhtä väriä kolmiota kohti, joka on laskettu kasvoilta normaali ja yhdestä valonlähteestä. []Lambertian malli[ antaa diffuusi intensiteetti: . C:ssä lasketaan normaalina kahden kolmion reunan ristituotteena (sen jälkeen kun vertices on muunnettu maailman tilaan), sitten kerrot valon voimakkuuden kolmiolla.
Syvyyden lisäämiseksi on toteutettava Gouraud-varjostus[ (vertex-normaalit, interpoloitu sirpaleiden yli) tai Phong-varjostus[ (per-pikseli normaalit). Jälkimmäinen edellyttää interpolointia maailman asennoissa ja normaaleissa olosuhteissa, sitten valaistuksen laskentaa fragmenttia kohti kalliimpia mutta dramaattisesti parempia tuloksia.
Moottorin rakentaminen C: Käytännön vaiheet
Let.S kävelemällä läpi rakentaa minimaalinen ohjelmisto 3D moottori tyhjästä. Tavoitteena on tehdä pyörivä kuution ympäristön ja hajavalon päälle 640×480 pikseli ikkunaan.
Vaihe 1 ... Aseta pikselipuskuri
Määrittele rungon ja syvyyden muistipuskuri: ja . Tyhjennä runkopuskuri mustaksi ja syvyyspuskuri 1,0 (far plane) jokaiseen kehykseen.
Vaihe 2 . Määrittele kohtaustiedot
Kuusi kasvot (12 kolmiot) vaativat 12×3 = 36 vertices. Säilytä ne joukko rakennetta kanssa asento (3 kelluu) ja väri (3 kelluu RGB). Esimäärittele 8 ainutlaatuinen kuution kulmat ja kuusi kasvon väriä. Käytä indeksipuskuri välttää päällekkäisyyttä vertices.
Vaihe 3 ... .........................................................................................................................................................................................................................................................
Jokainen runko, laskea mallimatriisi kulmasta (esim., pyörittääY(aika)), näkymämatriisi kiinteästä kamerasta katsellen alkuperää, ja projektiomatriisi. Yhdistä ne yhdeksi MVP-matriisiksi: . Muunna jokainen huippupiste kertomalla [. Sitten suorita perspektiivin jako (jaa x,y,z w) saadaksesi normalisoidut laitekoordinaatit (−1-+1). Kartta näyttökoordinaatteihin: , [] (y ylösalaisin). Pidä NDC z syvyystestausta varten.
Vaihe 4 ... Rasterize and Shade
Kullekin kolmiolle, käytä scanline-menetelmää. Kävellessäsi pikseleitä, interpoloi syvyys ja myös interpoloi per-vertex-attribuutti kuten maailman-avaruuden sijainti (Fong) tai huippupiste normaali (Gouraud). Käytä Lambertian diffuusi yhtälö. Kirjoita lopullinen väri framebufferille, jos syvyystesti läpäisee.
Vaihe 5 ... Näyttö
Käytä SDL:ää (Simple DirectMedia Layer) tai vastaavaa kirjastoa ikkunan luomiseen ja framebufferin pilkkomiseen. Esimerkiksi SDL2:lla , , , [], [[[]] ja [] kunkin kehyksen yhteydessä.
Tämä ohjelmistopolku toimii suorittimen, joten suorituskyky on rajoitettu muutamaan tuhanteen kolmioon per runko. Kun mukava, voit korvata rasterization kerros OpenGL, lataamalla raskas työ GPU ja säilyttämällä transformaatio ja kohtaus logiikka C.
Optimoi moottorisi
Perusmoottori on hidas. Useat optimoinnit ovat välttämättömiä reaaliaikaisen suorituskyvyn kannalta:
- Takanapäinen harvennus:[) Ohita kolmiot, joiden normaalit pisteet ovat kaukana kamerasta. Laske projektiokolmion allekirjoitettu alue (2D) tai tarkista kasvojen pistetuote normaalilla näköalalla.
- Ruokanpoisto:[ Testaa kohteen rajalaatikkoa näkymän kuutta tasoa vasten. Jos se on kokonaan ulkona, jätä koko esine huomiotta.
- Korjattu piste aritmeettinen:[ Korvaa kelluva piste toiminta kokonaisluku matematiikka tiukka rasterisaatio silmukat. Monet moottorin rakentajat käyttävät 16.16 kiinteä piste scanline interpolointi.
- ]Esitransform välimuisti:[ Vältä muuntamasta samaa huippupistettä useita kertoja muuttamalla kaikki vertices silmän kerran, sitten käyttäen indeksejä.
- Tyhjennetty kehyspuskuri kirjoittaa:[ Kirjoita pikselit muistijärjestykseen (vasen oikealle, ylhäältä alas) maksimoidaksesi välimuistin osumat.
Nämä tekniikat voivat työntää ohjelmiston renderöintilaite 3...5 fps 60 fps varten kohtaukset kohtalaisen monimutkaisia (esim. muutama sata kolmiota).
Moottorin laajentaminen
Kun vankka perusta on olemassa, voit lisätä ominaisuuksia asteittain:
- Tekstinkartoitus:[ Säilytä 2D-kuvia ja interpoloi UV-koordinaatit kolmioiden välillä. Suorita bilineaarinen suodatus, jotta tulokset ovat sujuneet.
- Vahva varjostus:[ Lisää epearly kohokohtia (Blinn-Phong), ympäristön okkluusio, tai jopa varjokarttoja.
- Paikanhallinta:[ Käytä oktree- tai BSP-puuta nopeasti määrittääksesi, mitkä kohteet ovat näkyvissä.
- Käyttäjän vuorovaikutus:[ Käsinäppäimistö ja hiiren syöte kameran kiertoradalle tai poimi kohteita.
- Pipeliinin abstraktio:[ Suunnittele varjostinjärjestelmä: määrittele huippupiste ja fragmentti toiminnot funktioosoittimina, jolloin joustava renderointi ilman uudelleenkomplifiointi.
Resurssit ja jatkolukeminen
Syventää ymmärrystäsi, tutkia klassisia tekstejä ja online-opetusohjelmia, jotka innoittivat tätä moottoria:
- Scratchhapixel [ . Syvälliset selitykset säteen jäljittämisestä, rasterisaatiosta ja matematiikasta.
- OpiOpenGL . Moderni OpenGL-opetusohjelma; aloita ...Hei kolmio...
- Wikipedia: 3D-projektio . Muodollinen matematiikka perspektiivin ja ortografisten matriisejen takana.
3D-moottorin rakentaminen C:ssä on graafisten ohjelmoijien siirtymäriitti. Se opettaa paitsi tehokkaan koodin kirjoittamisen myös sen, miten ajatella kolmessa ulottuvuudessa ja säveltää suorituskykykriittisiä järjestelmiä. Aloita yhdellä pyörivällä kuutiolla, lisää sitten kolmioita, tekstuureja ja lopuksi luovuta se pois GPU:lle. Matka raaka C:stä täysin toimivaan moottoriin paljastaa magian jokaisen pikselin takana näytöllä.