In dit derde hoofdstuk, waarin we dieper ingaan op het maken van 3D-games, zullen we ons concentreren op wat er met de 3D-wereld kan gebeuren na hoekverwerking en rastering van scènes. Configuratie is een van de belangrijkste fasen bij het renderen, hoewel alles wat er gebeurt, is dat de kleuren van een tweedimensionaal raster van gekleurde blokken worden berekend en gewijzigd.

Veel van de visuele effecten die tegenwoordig in games worden gezien, zijn afhankelijk van het slimme gebruik van texturen - zonder deze zouden games saai en levenloos zijn. Dus laten we de sprong wagen en kijken hoe deze werken!

Zoals altijd, als je niet klaar bent om een ​​diepe duik in weefsel te nemen, raak dan niet in paniek - je kunt aan de slag 3D-spelcreatie 101. Maar als je eenmaal voorbij de basis bent, lees dan verder voor onze volgende blik op de wereld van 3D-graphics.

Hoofdstuk 0: 3D-spelcreatie 101
De grafieken uitgelegd maken

Aflevering 1: Hoe 3D-spelweergave werkt: hoekweergave
Een diepere duik in de wereld van 3D-graphics
Deel 2: Hoe 3D-spelweergave werkt: rasteren en raytracing
Van 3D naar Flat 2D, POV en Verlichting
Deel 3: Hoe het maken van 3D-games werkt: textureren
Bilineaire, trilineaire, anisotrope filtering, Tuber Mapping en meer

Laten we simpel beginnen

Kies de best verkochte 3D-games van de afgelopen 12 maanden en ze zullen allemaal één ding gemeen hebben: textuurkaarten (of gewoon texturen). Dit is een veel voorkomende term, de meeste mensen zullen hetzelfde beeld creëren als ze aan texturen denken: een eenvoudig, plat vierkant of rechthoek met een afbeelding van een oppervlak (gras, steen, metaal, kleding, gezicht, enz.).

Maar bij gebruik in meerdere lagen en samengesteld met behulp van complexe rekenkunde, kan het gebruik van deze basisafbeeldingen in een 3D-scène verbluffend realistische afbeeldingen opleveren. Om te zien hoe dit mogelijk is, laten we ze helemaal overslaan en kijken hoe objecten in de 3D-wereld eruit zouden kunnen zien zonder hen.




Zoals we in eerdere artikelen zagen, bestaat de 3D-wereld uit hoekpunten - eenvoudige vormen die worden verplaatst en vervolgens worden gekleurd. Deze worden vervolgens gebruikt om de primitieven te maken, die op hun beurt worden gecomprimeerd tot een 2D-pixelraster. Omdat we geen texturen zullen gebruiken, moeten we deze pixels inkleuren.



Een methode die kan worden gebruikt heet is vlakke schaduwhoudt in dat je de kleur van het eerste hoekpunt van de primitief krijgt en die kleur vervolgens gebruikt voor alle pixels in het raster die onder de vorm vallen. Het ziet er zo uit:




Uiteraard is dit geen realistische theepot, in ieder geval is de kleur van het oppervlak verkeerd. Kleuren springen van het ene niveau naar het andere, er is geen vloeiende overgang. Een oplossing voor dit probleem zou kunnen zijn om iets te gebruiken dat Gouraud-schaduw.



Dit is een bewerking die de kleuren van de hoekpunten neemt en berekent hoe de kleur verandert over het oppervlak van de driehoek. De gebruikte wiskunde lineaire interpolatieHoewel dit mooi klinkt, betekent het in werkelijkheid dat als een primitieve kant 0,2 rood van kleur is en de andere kant 0,8 rood, dat het midden van de vorm een ​​kleur heeft tussen 0,2 en 0,8 (d.w.z. 0,5).

Het is relatief eenvoudig te doen en het belangrijkste voordeel is snelheid. Veel vroege 3D-spellen gebruikten deze techniek omdat de hardware die de berekeningen deed, beperkt was door wat het kon doen.




Maar zelfs dat heeft zijn problemen, want als een licht precies in het midden van een driehoek wijst, kunnen zijn hoekpunten (hoekpunten) het misschien niet goed vangen. Hierdoor kunnen highlights die door licht worden veroorzaakt volledig over het hoofd worden gezien.




Flat- en Gouraud-schaduwen zitten in het renderarsenaal, terwijl de bovenstaande voorbeelden duidelijke kandidaten zijn om texturen te gebruiken om ze te verbeteren. En om beter te begrijpen wat er gebeurt als een textuur op een oppervlak wordt aangebracht, gaan we terug in de tijd... terug naar 1996.

Een korte geschiedenis van games en GPU's

Quake is een mijlpaalspel dat 23 jaar geleden is uitgebracht id-software. Hoewel het niet de eerste game was die 3D-polygonen en texturen gebruikte om de omgeving te creëren, was het een van de eersten die ze allemaal zo effectief gebruikte.

Een ander ding dat hij deed, was laten zien wat er met OpenGL kon worden gedaan (de grafische API was nog in de eerste revisie), en het hielp ook een heel eind bij de verkoop van het eerste grafische kaartproduct. Commentaar ve 3Dfx Vudu.

Vergeleken met de huidige normen was Voodoo uiterst eenvoudig: geen ondersteuning voor 2D-graphics, geen vertex-rendering en alleen de basis van pixelrendering. Het was nog steeds een schoonheid:

Het had een hele chip (TMU) om een ​​pixel uit een textuur te halen en vervolgens een andere chip (FBI) om het te mengen met een pixel uit het raster. Het kan een paar extra's doen, zoals het maken van mist of transparantie-effecten, maar dat was het bijna.

Als we een overzicht nemen van de architectuur achter het ontwerp en de werking van de grafische kaart, kunnen we zien hoe deze processen werken.

De FBI-chip neemt twee kleurwaarden en combineert ze; een van hen kan een waarde zijn van een textuur. Het collatieproces is wiskundig vrij eenvoudig, maar verschilt enigszins tussen wat er precies wordt gemengd en welke API wordt gebruikt om de instructies uit te voeren.

waar we ook naar kijken Direct3D-aanbiedingen Wat betreft overvloeifuncties en overvloeibewerkingen, kunnen we zien dat elke pixel eerst wordt vermenigvuldigd met een getal tussen 0,0 en 1,0. Dit bepaalt hoeveel van de kleur van de pixel het uiteindelijke uiterlijk zal beïnvloeden. Vervolgens worden de twee aangepaste pixelkleuren opgeteld, afgetrokken of gedupliceerd; in sommige functies is de bewerking een logische uitdrukking waarbij altijd zoiets als de helderste pixel wordt geselecteerd.

Bovenstaande afbeelding is een voorbeeld van hoe dit in de praktijk werkt; de factor die wordt gebruikt voor de linkerpixel alfa waarde. Dit nummer transparant pixels.

De rest van de stappen omvat het toepassen van een mistwaarde (overgenomen uit een getallentabel die door de programmeur is gemaakt en vervolgens dezelfde mengberekening doet); enkele zichtbaarheids- en transparantiecontroles en aanpassingen uitvoeren; voordat u uiteindelijk de kleur van de pixel naar het geheugen op de grafische kaart schrijft.

Waarom geschiedenisles? Ondanks de relatieve eenvoud van het ontwerp (vooral in vergelijking met moderne ontwikkelaars), legt het proces de basisprincipes van texturen uit: neem wat kleurwaarden en meng ze zodat de modellen en omgevingen eruitzien hoe ze eruit zouden moeten zien in een bepaalde situatie.

De games van vandaag doen dit nog steeds, het enige verschil is de hoeveelheid gebruikte texturen en de complexiteit van mengberekeningen. Samen simuleren ze de visuele effecten die te zien zijn in films, of hoe licht interageert met verschillende materialen en oppervlakken.

De basis van texturen

Voor ons is een textuur een plat, 2D-beeld dat wordt toegepast op de polygonen waaruit de 3D-structuren in het weergegeven frame bestaan. Voor een computer is het niets meer dan een klein blok geheugen in de vorm van een 2D-array. Elk item in de array vertegenwoordigt een kleurwaarde voor een van de pixels in de textuurafbeelding (beter bekend) tekstvuller - textuurpixels).

Elk hoekpunt in een veelhoek heeft 2 coördinaten (meestalus sen, v) vertelt u welke pixel in de textuur eraan is gekoppeld. Het hoekpunt zelf heeft 3 sets coördinaten (X ve Z) en het proces van het verbinden van teksten met hoekpunten wordt genoemd. textuurtoewijzing.

Om dit in actie te zien, gaan we terug naar een tool die we meerdere keren hebben gebruikt in deze serie artikelen: Realtime weergave WebGL hulpmiddel. Voor nu, z coördineer vanuit de hoeken en houd alles in een plat vlak.

Van links naar rechts hebben we de textuur sen, v coördinaten direct toegewezen aan hoekpunten x, ja coördinaten. Dan de bovenhoeken y coördinaten zijn toegenomen, maar de textuur is naar boven uitgerekt omdat de textuur er nog steeds rechtstreeks op wordt toegewezen. In de uiterst rechtse afbeelding, de textuur die deze keer is veranderd: u waarden worden verhoogd, maar dit zorgt ervoor dat het weefsel wordt verpletterd en vervolgens terugvalt.

Omdat het weefsel nu effectief langer is, hoewel hoger u De waarde moet binnen de primitieve passen - in wezen wordt de textuur gedeeltelijk herhaald. Dit is een manier om iets te doen dat in veel 3D-games wordt gezien: therhaling. Veelvoorkomende voorbeelden hiervan zijn te vinden in scènes met rots- of graslandschappen of bakstenen muren.

Laten we nu de toon zetten om primitiever te zijn en diepte terug in het spel te brengen. Wat we hieronder hebben, is een klassiek landschapsbeeld, maar zoals de borsttextuur wordt gekopieerd en herhaald tussen primitieven.

Nu is deze borsttextuur 66 kilo in origineel gif-formaat en heeft een resolutie van 256 x 256 pixels. De oorspronkelijke resolutie van het deel van het frame dat wordt ingenomen door krattexturen is 1900 x 680, dus alleen in termen van pixel 'gebied' zou dit gebied slechts 20 krattexturen moeten kunnen weergeven.

We krijgen duidelijk meer dan 20 paden, dus veel borsttexturen op de achtergrond heel Kleiner dan 256 x 256 pixels. Dat zijn ze inderdaad en ze hebben een proces doorlopen textuurreductie (ja, dat is een woord!). Laten we het nu opnieuw proberen, maar deze keer kwam het dicht bij een van de kisten.

Merk op dat de textuur slechts 256 x 256 pixels groot is, maar hier kunnen we zien dat een textuur meer dan de helft van de breedte van de afbeelding van 1900 pixels breed is. Het ging door iets genaamd textuur weefselvergroting.

Deze twee textuurprocessen vinden voortdurend plaats in 3D-games, omdat als de camera door de scène beweegt of modellen in- en uitzoomen, alle texturen die op primitieven worden toegepast, samen met de polygonen moeten worden geschaald. Wiskundig gezien is dit geen probleem, zelfs de eenvoudigste geïntegreerde grafische chips flitsen in zo'n bedrijf. Weefselreductie en -vergroting brengen echter nieuwe problemen met zich mee die op de een of andere manier moeten worden opgelost.

Voer mini-texturen in

Het eerste probleem dat moet worden opgelost, is voor verre texturen. Kijken we nog eens naar het eerste kratlandschapsbeeld, dan zijn die richting de horizon slechts enkele pixels groot. Een afbeelding van 256 x 256 pixels in zo'n kleine ruimte proberen te persen, is om twee redenen zinloos.

Ten eerste neemt een kleinere textuur minder geheugenruimte in beslag op de grafische kaart, wat handig is om te proberen een kleine hoeveelheid cache te plaatsen. Dit betekent dat het minder waarschijnlijk is dat het uit de cache wordt verwijderd, en herhaald gebruik van deze textuur zal het volledige prestatievoordeel halen uit gegevens die zich in het nabijgelegen geheugen bevinden. De tweede reden waarom we hier even zijn, omdat het verband houdt met hetzelfde probleem voor ingezoomde texturen.

Een veel voorkomende oplossing voor het gebruik van grote texturen die worden verpletterd tot kleine primitieven, Bij elkaar passen. Dit zijn verkleinde versies van de originele textuur; De game-engine zelf kan worden gebouwd (met behulp van het bijbehorende API-commando om dit te doen) of het kan vooraf worden gemaakt door game-ontwerpers. Elk mipmap-textuurniveau heeft de helft van de lineaire afmetingen van het vorige.

Voor de borsttextuur zou het zoiets zijn als: 256 x 256 → 128 x 128 → 64 x 64 → 32 x 32 → 16 x 16 → 8 x 8 → 4 x 4 → 2 x 2 → 1 x 1.

De mipmaps zijn allemaal gebundeld zodat de textuur nog steeds dezelfde bestandsnaam heeft, maar nu groter. Het weefsel is zo verpakt dat: sen, v De coördinaten bepalen niet alleen welke texel je moet toepassen op een pixel in het frame, maar ook van welke mipmap. Programmeurs coderen vervolgens de renderer om de te gebruiken mipmap te bepalen op basis van de dieptewaarde van de vierkante pixel, dus als deze te hoog is, is de pixel ver weg, zodat een kleine mipmap kan worden gebruikt.

Lezers met scherpe ogen hebben misschien de keerzijde van mipmaps gezien, en dit gaat ten koste van grotere texturen. De originele borsttextuur was 256 x 256 pixels, maar zoals je kunt zien in de afbeelding hierboven, is de mipmap-textuur nu 384 x 256 pixels. Ja, er is veel vrije ruimte, maar de totale toename tot ten minste één van de texturen is 50%, ongeacht hoe u kleinere texturen verpakt.

Dit geldt echter alleen voor kant-en-klare mipmaps; Als de game-engine is geprogrammeerd om ze correct te genereren, kan de toename nooit meer zijn dan 33% van de oorspronkelijke textuurgrootte. U krijgt dus prestatievoordelen en visuele verbeteringen voor een relatief kleine toename van het geheugen op texture mipmaps.

Hieronder is de uit/aan vergelijking van texture mipmaps:

Aan de linkerkant van de afbeelding worden krattexturen gebruikt 'zoals ze zijn', wat resulteert in een korrelig uiterlijk en zogenaamd moiré patronen weg. Aan de rechterkant resulteert het gebruik van mipmaps echter in een veel vloeiendere overgang door het landschap, waarbij de textuur van de kist verandert in een consistente kleur aan de horizon.

Wie wil er echter wazige texturen die de achtergrond van hun favoriete spel bederven?

Bilineair, trilineair, anisotroop - allemaal Grieks voor mij

Het proces van het selecteren van pixels uit een textuur die op een pixel in een frame moet worden toegepast, heet textuur bemonsteringen in een perfecte wereld, zijn grootte, locatie, richting, enz. hoe dan ook, het zou een textuur zijn die precies bij de primitieve past. Met andere woorden, texturesampling is niets meer dan een vlakke 1-op-1 pixel-naar-pixel mapping.

Aangezien dit niet het geval is, moet bij textuurbemonstering rekening worden gehouden met een aantal factoren:

  • Is de textuur vergroot of verkleind?
  • Is de textuur origineel of een mipmap?
  • Onder welke hoek wordt de textuur weergegeven?

Laten we ze een voor een analyseren. De eerste is duidelijk genoeg: als de textuur wordt vergroot, zal er meer tekst over de pixel in de primitief liggen; met verkleinen is het andersom, elke texel moet nu meerdere pixels beslaan. Dit is een beetje een probleem.

Ten tweede, aangezien mipmaps worden gebruikt om het probleem van textuurbemonstering met primitieven op afstand te omzeilen, worden de texturen in een hoek gelaten. En ja, dat is ook een probleem. Waarom is dat? Omdat alle texturen 'face open' worden weergegeven voor een weergave, of ze zijn allemaal wiskundig: de normaal van het textuuroppervlak is hetzelfde als de oppervlaktenormaal die boven de textuur wordt weergegeven.

Daarom, om te weinig of te veel textuur en textuur onder een hoek te hebben, textuur filteren. Als u deze actie niet gebruikt, krijgt u dit:

Hier hebben we de borsttextuur vervangen door een R-lettertextuur om duidelijker te laten zien hoeveel rommel het zal krijgen zonder textuurfiltering!

Grafische API's zoals Direct3D, OpenGL en Vulkan bieden allemaal dezelfde soorten bereikfiltering, maar gebruiken er verschillende namen voor. Eigenlijk gaat het allemaal zo:

  • dichtstbijzijnde punt bemonstering
  • Lineaire textuurfiltering
  • Anisotrope textuurfiltering

Voor alle doeleinden, dichtstbijzijnde punt bemonstering als het niet filtert - het is omdat het de pixel is die het dichtst bij de pixel staat en waarvoor de texturen moeten worden gesampled (d.w.z. gekopieerd uit het geheugen) en vervolgens gemengd met de originele kleur van de pixel.

Hier komt lineaire filtering te hulp. Verplicht sen, v texel-coördinaten worden naar de hardware gestuurd voor bemonstering, maar in plaats van de texel die het dichtst bij deze coördinaten ligt, krijgt de sampler vier texel Deze bevinden zich direct boven, onder, links en rechts van degene die is geselecteerd met behulp van dichtstbijzijnde puntbemonstering.

Deze 4 textielsoorten worden vervolgens gemengd met behulp van een gewogen formule. In Vulkan is de formule bijvoorbeeld:

T "Kleur", f Voor de uitgelekte en van 1 tot 4 zijn vier bemonsterde textielsoorten. Waarden alfa ve bèta hoe ver van het punt gedefinieerd door sen, v coördinaten komen uit het midden van het weefsel.

Gelukkig gebeurt iedereen die betrokken is bij 3D-games, of het nu gaat om het spelen of maken van games, automatisch op deze grafische verwerkingschip. In feite deed de TMU-chip in 3dfx Voodoo dit: hij bemonsterde 4 singletons en schudde ze vervolgens. Direct3D noemt het vreemd binaurale filtering, maar sinds de tijd van Quake en Voodoo's TMU-chip, zijn grafische kaarten alleen in staat geweest om bilineaire filtering uit te voeren in één klokcyclus (als de textuur comfortabel in het nabije geheugen zit natuurlijk).

Lineaire filtering kan naast mipmaps worden gebruikt en als je echt fancy wilt worden met je filtering, kun je 4 teksten van een textuur nemen, dan nog eens 4 van het volgende niveau van mipmaps en ze vervolgens samenvoegen. En de naam van Direct3D ervoor? trilineair filteren. Wat tri over dit proces? Jouw gok is net zo goed als de onze...

De laatst genoemde filtermethode heet anizotroop. Dit is eigenlijk een aanpassing aan het proces bij bilineaire of trilineaire filtering. aanvankelijk graad van anisotropie primitief oppervlak (en verrassend complex) - deze waarde verandert de beeldverhouding van de primitief vanwege zijn oriëntatie:

De afbeelding hierboven toont dezelfde vierkante primitief met zijden van gelijke lengte; maar als we ons verder van ons perspectief verwijderen, ziet het eruit als een vierkante rechthoek en wordt de breedte groter dan de hoogte. Dus de primitief aan de rechterkant heeft een grotere anisotropie dan die aan de linkerkant (en in het geval van het vierkant is de graad precies nul).

In de meeste van de huidige 3D-games kun je anisotrope filtering inschakelen en vervolgens het niveau aanpassen (1x tot 16x), maar wat verandert dat eigenlijk? De instelling regelt het maximale aantal extra Texelse monsters dat per origineel lineair monster wordt genomen. Laten we bijvoorbeeld zeggen dat het spel is ingesteld om 8x anisotrope bilineaire filtering te gebruiken. Dit betekent dat het 32 ​​waarden retourneert in plaats van slechts 4 tekstwaarden te nemen.

Het is duidelijk dat het gebruik van anisotrope filtering het volgende kan realiseren:

Scroll gewoon een beetje omhoog en vergelijk de dichtstbijzijnde puntsampling voor maximaal 16x anisotrope trilineaire filtering. Zo zacht, bijna heerlijk!

Maar er moet een prijs zijn voor al die lekkere boterachtige textuursmaak, en het zijn zeker prestaties: alle maximale, anisotrope trilineaire filtering levert 128 samples van een textuur op voor elke gerenderde pixel. Zelfs voor de beste van de nieuwste GPU's kan dit niet in een enkele klokcyclus worden gedaan.

Als we zoiets krijgen als AMD Radeon RX 5700 XTDe textuureenheden in de processor kunnen elk 32 texel-adressen in één klokcyclus uitschakelen, vervolgens 32 texels uit het geheugen laden (elk 32 bits groot) in een andere klokcyclus en er vervolgens 4 bij elkaar zetten om te markeren. Daarom is het geschud voor 128 texel-exemplaren die minimaal 16 klokcycli nodig hebben.

Nu is de basiskloksnelheid van de 5700 XT 1605 MHz, dus zestien cycli duren slechts 10 nanosaniye. Doe dit gewoon voor elke pixel in het 4K-frame. een weefseleenheid zou nog steeds maar 70 milliseconden duren. Ok, misschien zijn prestaties niet zo belangrijk!

Zelfs in 1996 waren 3Dfx Voodoo behoorlijk handig als het ging om het hanteren van texturen. Het kon maximaal 1 bilineair gefilterde texel per klokcyclus bereiken en betekende dat 50 miljoen tex per seconde kon worden gesneden terwijl de TMU-chip op 50 MHz zwaaide. Een game met 800 x 600 en 30 fps vereist slechts 14 miljoen bilineaire gefilterde tekst per seconde.

Dit alles veronderstelt echter dat de texturen zich in het nabije geheugen bevinden en dat er slechts één tex wordt toegewezen aan elke pixel. Twintig jaar geleden was het idee om meerdere texturen op een beleid te moeten toepassen bijna volledig vreemd, maar nu is het gemeengoed. Laten we eens kijken waarom deze verandering heeft plaatsgevonden.

Verlicht de weg naar verbluffende beelden

Om te helpen begrijpen hoe weven zo belangrijk werd, kun je deze scène uit Quake bekijken:

Het is een donker beeld, dat was de aard van deze game, maar je kunt zien dat de duisternis niet overal hetzelfde is - delen van de muren en de vloer zijn helderder dan andere om het gevoel van algemene verlichting in dat gebied te geven.

De primitieven die de zijkanten en de grond vormen, hebben dezelfde textuur erop toegepast, maar er is een tweede textuur genaamd lichtkaartwordt vermengd met Texelse waarden alvorens te matchen met vierkante pixels. In de tijd van de aardbeving werden lichtkaarten vooraf berekend en gemaakt door de game-engine en gebruikt om statische en dynamische lichtniveaus te creëren.

Het voordeel van het gebruik ervan was dat complexe belichtingsberekeningen werden uitgevoerd op texturen in plaats van hoeken, waardoor met name het uiterlijk van een scène werd verbeterd en er zeer weinig prestatiekosten waren. Het is natuurlijk niet perfect: zoals je op de grond kunt zien, is de grens tussen de verlichte gebieden en die in de schaduw heel duidelijk.

In veel opzichten is een lichtgewicht kaart gewoon een andere textuur (onthoud dat ze allemaal niets meer zijn dan 2D-gegevensarrays), dus waar we hier naar kijken is een vroeg gebruik van wat bekend staat als multitextuur. Zoals de naam al doet vermoeden, is het een proces waarbij twee of meer texturen op een principe worden toegepast. Het gebruik van lichtgewicht kaarten in Quake was een oplossing om de beperkingen van Gouraud-shading te overwinnen, maar naarmate de mogelijkheden van grafische kaarten toenam, deden multithreaded toepassingen dat ook.

3Dfx Voodoo was, net als andere kaarten uit zijn tijd, beperkt in hoeveel het kon doen in een render voorbij lopen. Dit is in wezen een complete renderreeks: van het renderen van de hoeken tot het rasteren van het frame en het vervolgens veranderen van de pixels in een definitieve framebuffer. Twintig jaar geleden voerden games bijna altijd één pas uit.

Dit was omdat het twee keer renderen van de hoekpunten erg kostbaar was in termen van prestaties, omdat je gewoon meer textuur wilde toepassen. Een paar jaar na Voodoo moesten we wachten tot het beschikbaar kwam voordat we multi-threaded ATI Radeon en Nvidia GeForce 2 grafische kaarten in een enkele render-pass konden maken.

Deze GPU's hadden meerdere textuureenheden per pixelweergavesectie (d.w.z. pijplijn:), dus een bilineair gefilterd Texel uit twee aparte weefsels halen was een makkie. Dit maakte light mapping nog populairder, waardoor games volledig dynamisch konden zijn, waarbij de lichtwaarden werden gewijzigd op basis van veranderingen in de game-omgeving.

Maar er is zoveel meer dat kan worden gedaan met meerdere texturen, dus laten we eens kijken.

Het is normaal om de hoogte te vermenigvuldigen

In deze serie artikelen over 3D-rendering hebben we niet besproken hoe de rol van de GPU echt bij het hele punt past (dat zullen we doen, nog niet!). Maar als je terugkomt Aflevering 1en kijk naar al het complexe werk aan vertex-rendering, je zou kunnen denken dat dit het moeilijkste deel van de hele array is voor de GPU om te verwerken.

Dat is al lang zo en gameprogrammeurs hebben hun best gedaan om deze werklast te verminderen. Dit betekende dat je naar de zak met visuele trucs moest gaan en zoveel mogelijk snelkoppelingen en cheats eruit moest halen, waardoor je hetzelfde visuele uiterlijk kreeg van het gebruik van veel hoekpunten overal, maar niet echt veel van hen om het te starten.

En de meeste van deze trucs, hoogtekaarten ve gewone kaarten. De twee zijn gerelateerd aan het feit dat de tweede kan worden gemaakt vanaf de eerste, maar laten we nu eens kijken naar een techniek genaamd: hobbeltoewijzing.

Bump mapping omvat het gebruik van een 2D-array, een hoogtekaart genaamd, die eruitziet als een enkele versie van de originele textuur. De afbeelding hierboven heeft bijvoorbeeld een realistische baksteenstructuur die is aangebracht op 2 vlakke oppervlakken. De textuur- en hoogtekaart ziet er als volgt uit:

De kleuren van de hoogtekaart vertegenwoordigen de normalen van het baksteenoppervlak (we hebben besproken wat de normaal is Aflevering 1 van deze serie artikelen). Wanneer de rendervolgorde het punt bereikt waarop de steentextuur op het oppervlak wordt aangebracht, wordt een reeks berekeningen gemaakt om de kleur van de steentextuur op normaal aan te passen.

Hierdoor zien de stenen er meer 3D uit, ook al zijn ze nog perfect vlak. Vooral als je goed naar de randen van de stenen kijkt, zie je de grenzen van de techniek: de textuur ziet er een beetje vervormd uit. Maar voor een snelle truc om meer details aan een oppervlak toe te voegen, is bump mapping erg populair.

Een normale kaart is als een hoogtekaart, maar de kleuren van die textuur zijn de normaal zelf. Met andere woorden, er is geen berekening nodig om de hoogtekaart naar normaal te converteren. Je vraagt ​​je misschien af ​​hoe kleuren kunnen worden gebruikt om een ​​pijl in de ruimte weer te geven. Het antwoord is simpel: elke texel heeft een specifieke R, G, B waarden (rood, groen, blauw) en deze nummers zijn direct X ve Z waarden voor de normaalvector.

In het bovenstaande voorbeeld laat het linker diagram zien hoe de richting van de normaal verandert op een ruw oppervlak. Om dezelfde normalen in een platte structuur weer te geven (middelste diagram), kennen we ze een kleur toe. In ons geval, R, G, B het verhogen van de waarden (0.255.0) voor rechtdoor en vervolgens de hoeveelheden rood voor links en blauw voor rechts.

Merk op dat deze kleur niet vermengd is met de originele pixel - het vertelt de processor in welke richting de normaal is gericht, zodat de camera de hoeken tussen de lichten en het gestructureerde oppervlak nauwkeurig kan berekenen.

De voordelen van bump en normal mapping komen pas echt tot uiting wanneer dynamische verlichting in de scène wordt gebruikt, en het renderingproces berekent de effecten van lichtveranderingen per pixel, niet per hoek. Moderne games gebruiken nu een stapel texturen om de kwaliteit van de uitgevoerde magie te verbeteren.

Deze realistisch ogende muur is ongelooflijk gewoon een plat oppervlak - de details over de baksteen en mortel zijn niet gemaakt met behulp van miljoenen polygonen. In plaats daarvan doet het slechts 5 texturen en veel slim wiskundig werk.

De hoogtekaart werd gebruikt om de normale kaart te genereren om de manier waarop de stenen schaduwen op zichzelf werpen en eventuele kleine veranderingen aan het oppervlak te simuleren. De ruwheidstextuur werd gebruikt om te veranderen hoe licht verschillende elementen van de muur reflecteert (bv. een afgeplatte baksteen reflecteert consistenter dan ruwe mortel).

De uiteindelijke kaart, met het label AO in de afbeelding hierboven, maakt deel uit van een proces dat ambient occlusie wordt genoemd: een techniek waar we in een later artikel dieper op in zullen gaan, maar voorlopig slechts schaduwen.

Textuurmapping is cruciaal

Textuur is absoluut essentieel voor gamedesign. Download de 2019-versie van Warhorse Studio Het Koninkrijk komt eraan: verlossing - Een first-person RPG die zich afspeelt in het 15e-eeuwse Bohemen, een oud land in Centraal-Oost-Europa. De ontwerpers wilden voor de betreffende periode een zo realistisch mogelijke wereld creëren. En de beste manier om de speler onder te dompelen in een leven van honderden jaren geleden, elk landschapsbeeld, gebouw, kledingset, haar, alledaagse voorwerpen enz. Het ging om de juiste uitstraling.

Elke unieke textuur in deze enkele afbeelding in het spel is gemaakt door de artiesten en het gebruik ervan door de render-engine die wordt bestuurd door de programmeurs. Sommige zijn klein, hebben basisdetails en hebben weinig zin om andere texturen te filteren of te verwerken (bijvoorbeeld kippenvleugels).

Anderen hebben een hoge resolutie en laten veel fijne details zien; anisotroop gefilterd en vermengd met normale kaarten en andere texturen - kijk maar naar het gezicht van de man op de voorgrond. De verschillende vereisten voor het textureren van elk element in de scène worden uitgelegd door de programmeurs.

Dit alles gebeurt nu in veel games, omdat spelers meer detail en realisme verwachten. Texturen zullen groeien en meer op een oppervlak worden gebruikt, maar het proces van het samplen van tekst en het toepassen ervan op pixels zal in wezen hetzelfde zijn als in de tijd van de aardbeving. De beste technologie, hoe oud ook, sterft nooit!