3D-spel Rendering II

3D-spel Rendering

 

Ta in lamporna: pixel scenen

Så nu kommer vi till det svåraste i alla steg i kedjan rendering. År sedan, var detta inget annat än en förpackning modellens kläder (aka texturer) på objekten i världen, med hjälp av informationen i bildpunkter (ursprungligen från hörn). Problemet här är att medan texturer och ramen är alla 2D, världen som de fästes har varit vridna, flyttade och omformas i vertex scenen. Ännu mer matematik är anställd att ta hänsyn till detta, men resultaten kan generera några konstiga problem.

I denna bild tillämpas en enkel checker board texturschemat på en plan yta som sträcker sig bort i fjärran. Resultatet är en skärande röra, med aliasing uppfödning sitt fula tryne igen. Lösningen innebär mindre versioner av textur kartor (kallas mipmaps), upprepad användning av data från dessa texturer (kallas filtrering), och även mer matematik, att föra det alla tillsammans. Effekten av detta är ganska uttalad:

Detta brukade vara riktigt hårt arbete för något spel att göra men det är inte längre fallet, eftersom den liberala användningen av andra visuella effekter, såsom reflektioner och skuggor, innebär att bearbetning av texturer bara blir en relativt liten del av pixeln bearbetning scenen . Spela spel på högre upplösningar också genererar en högre arbetsbelastning i rastrering och pixel stadier av renderingsprocessen, men har relativt liten inverkan i vertex scenen. Även om det ursprungliga färgen på grund av lampor sker i vertex scenen, kan finare ljuseffekter också vara anställd här.

I ovanstående bild, kan vi inte längre enkelt se färgen skiftar mellan trianglarna, ger oss intrycket att detta är en mjuk, sömlös objekt. I detta exempel, sfären faktiskt består från samma antal trianglar som vi såg i det gröna området tidigare i denna artikel, men den pixel färg rutin ger intrycket att det är har betydligt fler trianglar.

I massor av spel behöver pixel scenen köras några gånger. Exempelvis behöver en spegel eller sjön yta avspeglar världen, som det ser ut från kameran, har världen återges till att börja med. Varje körning genom kallas ett pass och en bildruta kan lätt innebära 4 eller fler pass för att producera den slutliga bilden.

Vertex scenen måste ibland göras igen, också, för att rita om världen ur ett annat perspektiv och använder den vyn som en del av scenen tittade på av spelet spelaren. Detta kräver användning av render mål–buffertar som fungerar som finalen lagra för ramen men kan användas som texturer i ett annat pass.

För att få en djupare förståelse av de potentiella komplexiteten av pixel scenen, Läs Adrian Courrèges’ ram analys av Doom 2016 och förundras över den otroliga mängden steg krävs för att göra en enskild bildruta i det spelet.

Allt detta arbete på ramen måste sparas till en buffert, antingen som en färdiga resultatet eller en tillfällig butik, och i allmänhet ett spel kommer att ha minst två buffertar i farten för den slutliga vyn: en kommer att vara ”pågående arbeten” och den andra är antingen väntar den övervaka för att komma åt det eller håller på att visas. Det måste alltid finnas en rambuffert tillgängliga att återge i, så när de är fullt, en åtgärd måste ske för att flytta saker och starta en ny buffert. Den sista delen i undertecknandet av en ram är ett enkelt kommando (t.ex. närvarande) och med detta, de sista bildrutan buffertarna växlas om, bildskärmen blir den sista bildrutan återges och nästa kan startas.

I den här bilden tittar från Ubisoft Assassin’s Creed Odyssey, vi på innehållet i en färdig rambuffert. Tänk på det som ett kalkylblad med rader och kolumner av celler, som innehåller inget mer än ett nummer. Dessa värden skickas till den bildskärm eller TV i form av en elektrisk signal, och färgen på skärmens pixlar ändras till önskade värden. Eftersom vi inte CSI: TechSpot med våra ögon, vi ser en platt, kontinuerlig bild men våra hjärnor tolka det som att ha djup – dvs 3D. En ram av gaming godhet, men med så mycket händer bakom kulisserna (ursäkta ordvitsen), det är värt att ta en titt på hur programmerare hanterar det hela.

 

Hantera processen: API: er och instruktioner

Räkna ut hur man gör ett spel utföra och hantera allt detta arbete (den matematik, hörn, texturer, lampor, buffertar, du namnge den…) är en gigantisk uppgift. Lyckligtvis finns det hjälp i form av vad som kallas en ansökan programmering gränssnitt eller API för kort.

API: er för rendering minska övergripande komplexiteten genom att erbjuda strukturer, regler och biblioteken av koden, som gör att programmerare att använda förenklade instruktioner som är oberoende av någon hårdvara som är inblandade. Plocka några 3D spel, släppt under senaste 3 åren för PC, och det har skapats med någon av tre berömda API: Direct3D eller OpenGL Vulkan. Det finns andra, särskilt i den mobila scenen, men vi ska sticka med de för denna artikel.

Medan det finns skillnader i fråga om ordalydelsen i instruktioner och verksamhet (t.ex. ett kodblock till processen pixlar i DirectX kallas pixelskuggning; i Vulkan, det kallas en fragment skuggning), slutresultatet av den återgivna ram inte är, eller mer snarare , bör inte vara annorlunda.

Där det blir gäller en skillnad ner till vilken maskinvara används för att göra alla rendering. Detta beror på att de instruktioner som utfärdas med API behöver översättas för hårdvara för att utföra–detta hanteras av enhetens drivrutiner och maskinvarutillverkare har att ägna massor av resurser och tid att förarna göra konverteringen så snabbt och korrekt som möjligt.

Låt oss använda en tidigare betaversion av Croteam’s 2014 spelet The Talos principen för att påvisa detta, eftersom den stöder 3 API: er som vi har nämnt. För att förstärka de skillnader som kombinationen av drivrutiner och gränssnitt kan ibland ge, körde vi standard inbyggda riktmärket på högsta visuella inställningar med en upplösning på 1080p. PC används körde på standard klockor och lekte en Intel Core i7 – 9700K, Nvidia Titan X (Pascal) och 32 GB DDR4 RAM.

– DirectX 9 = 188,4 fps genomsnittet

– DirectX 11 = 202,3 fps genomsnittet

– OpenGL = 87,9 fps medel

– Vulkan = 189,4 fps medel

En fullständig analys av konsekvenserna bakom dessa siffror är inte inom syftet med denna artikel, och de menar säkert inte att ett API är ‘bättre’ än någon annan (detta var en betaversion, glöm inte), så vi lämnar frågor med anmärkningen att programplaneringen för olika API presentera olika utmaningar och, för tillfället, kommer det alltid att finnas några variationer i prestanda. Generellt sett kommer att spelutvecklare välja det API som de är mest erfarna i att arbeta med och optimera sin kod på den grunden. Används ibland ordet motorn att beskriva rendering koden, men tekniskt en motor är det hela paketet som hanterar alla aspekter i ett spel, inte bara dess grafik.

Skapa ett fullständigt program, från grunden, att rendera en 3D-spel är ingen enkel sak, vilket är varför så många spel idag licens full system från andra utvecklare (t.ex. Unreal Engine); Du kan få en känsla av skalan genom att Visa open source-motorn för id Softwares Quake och bläddra igenom filen gl_draw.c – denna enda punkt innehåller instruktioner för olika rendering operationer som utförs i spelet, och utgör bara en liten del av den hela motorn. Skalvet är över 20 år, och hela spelet (inklusive alla tillgångar, ljud, musik, etc) är 55 MB i storlek; för kontrast, Ubisofts Far Cry 5keeps bara shaders används av spelet i en fil som är 62 MB i storlek.

 

Tid är allt: med rätt hårdvara

Allt som vi har beskrivit hittills kan beräknas och bearbetas av CPU av något datasystem; moderna x86-64 processorer enkelt stödja alla av matematik krävs och har ägnat delar i dem för sådana saker. Dock gör detta arbete att göra en ram innebär mycket repetitiva beräkningar och kräver en betydande mängd parallell bearbetning. Processorer inte slutligen har utformats för detta, eftersom de är alltför allmänna av krävs design. Specialiserade marker för detta slags arbete, naturligtvis kallas GPU (graphics processing Unit), och de är byggda för att göra matten behövs av lik DirectX och OpenGL Vulkan mycket snabbt och enormt parallellt.

Ett sätt att demonstrera detta är med hjälp av ett riktmärke som tillåter oss att göra en ram med en CPU och sedan använda specialiserad hårdvara. Vi använder V-ray nästa av kaos-gruppen; Det här verktyget gör faktiskt ray-tracing i stället för rendering vi har tittat på i den här artikeln, men mycket av siffertuggande kräver liknande hårdvara aspekter.

För att få en känsla av skillnaden mellan vad en CPU klarar och vad rätt, anpassade utformade hårdvara kan åstadkomma, vi sprang V-ray GPU riktmärket i 3 lägen: CPU bara GPU endast och sedan CPU + GPU tillsammans. Resultaten skiljer sig markant:

– CPU bara testa = 53 mpaths

– GPU bara testa = 251 mpaths

– CPU + GPU test = 299 mpaths

Vi kan ignorera måttenheterna i denna riktmärke, som en 5 x skillnad i produktionen är ingen struntsak. Men detta är inte ett mycket spel-liknande test, så låt oss prova något annat och gå lite gamla skolan med Futuremark’s 3DMark03. Köra testet för enkel vingar för Fury, vi kan tvinga den att göra alla vertex shaders (dvs alla de rutiner som gjort för att flytta och färg trianglar) använder CPU.

Resultatet inte borde verkligen komma som en överraskning men ändå, uttalas det långt mer än vad vi såg i V-ray test:

– CPU vertex shaders = 77 fps i genomsnitt

– GPU vertex shaders = 1580 fps i genomsnitt

Med Processorn hanterar alla vertex beräkningar, tog varje bildruta 13 millisekunder i genomsnitt som ska återges och visas; trycka att matematik på GPU droppar denna tid ända ner till 0,6 millisekunder. Med andra ord, var det mer än 20 gånger snabbare.

Skillnaden är ännu mer anmärkningsvärt om vi försöker mest komplexa test, Moder natur, i benchmark. Med CPU bearbetas vertex shaders var genomsnittliga resultatet en ynka 3.1 fps! Ta in GPU och den genomsnittliga hastigheten stiger till 1388 fps: nästan 450 gånger snabbare. Nu Glöm inte att 3DMark03 är 16 år gammal, och testet endast behandlas formhörnen på CPU–rastrering och pixel scenen gjordes fortfarande via GPU. Vad skulle det vara som om det var modernt och hela partiet var gjort i programvara?

 

Låt oss försöka Unigine’s Valley benchmark-verktyg igen–det är relativt nytt, grafiken it-processer är så mycket som de sett i spel som Ubisofts Far Cry 5; Det ger också en full mjukvaran-baserat renderare, utöver standard DirectX 11 GPU rutten. Resultaten behöver inte mycket av en analys men kör den lägsta kvalité versionen av DirectX 11 testet på GPU gav ett genomsnittligt resultat 196 bildrutor per sekund. Vilken version av programvaran? Ett par kraschar undan, mäktiga test PC marken ut ett genomsnitt av 0.1 bildrutor per sekund – nästan två tusen gånger långsammare.

Anledningen till en sådan skillnad ligger i matten och dataformat som 3D-rendering användning. I en CPU, det är den flytande punkt enheter (FPUs) inom varje kärna som utför beräkningarna; testet PC’S i7 – 9700K har 8 kärnor, var och en med två FPUs. Medan enheterna i Titan X är olika i design, kan de båda göra samma grundläggande matematik, på samma dataformat. Denna särskilda GPU har över 3500 enheter att göra en motsvarande beräkning och trots att de är inte klockat någonstans nära samma som CPU (1,5 GHz vs 4,7 GHz), GPU överträffar den centrala processorn genom ren enhet räknas.

En Titan X är inte ett mainstream grafikkort, skulle även en budgetmodell överträffa alla CPU, vilket är varför alla 3D-spel och API: er är utformade för dedikerad, specialiserad maskinvara. Känn dig fri att ladda ner V-ray, 3DMark eller någon Unigine riktmärke, och testa dina egna system–efter resultaten i forumet, så vi kan se hur väl utformade grafikprocessorer är för rendering grafik i spel.

Några ord innan avslutning

Detta var en kort körning genom av hur en ram i en 3D spelet skapas, från punkter i rymden till färgade pixlar på en bildskärm.

På dess mest grundläggande nivå är hela processen ingenting mer än arbetar med siffror, eftersom det är alla dator göra ändå. En hel del har dock utelämnats i denna artikel, att hålla det fokuserade på grunderna (vi kommer sannolikt följer senare med djupare dyk in i hur datorgrafik görs). Vi tog inte med någon av faktiska matematik används, såsom den euklidiska linjär algebra, trigonometri och differentialkalkyl utförs av vertex och pixel shader; Vi slätade över hur texturer bearbetas genom statistiska urval, och lämnade åsido cool visuella effekter som skärmen utrymme ambient occlusion, ray trace de buller, hög dynamik imaging, eller temporal kantutjämning.

Men när du nästa eld upp en runda av samtal av Mario: Deathduty Battleyard, vi hoppas att inte bara kommer du att se grafik med en ny känsla av förundran, men du kommer vara klåda att få veta mer.