5 gode råd til optimering af grafikydelsen i dit spil

Et godt spil har for mig en fængende historie, spændende gameplay og en fed grafisk stil, men alt dette er dog hurtigt ødelagt hvis spillet ikke kører optimalt.

Grafik-rendering, specielt i 3D spil, er et af de områder som virkelig presser dit system, så jeg vil her give mine 5 gode råd, der kan hjælpe med at maksimere ydelsen.

Model geometri

Den første optimering starter med selve 3D-modellen. Det er vigtigt at holde antallet af polygoner så lavt som muligt, da GPUen skal processere hver enkelt. Overvej derfor konteksten for din model i spilverdenen. Det kan være, at spilleren aldrig ser bagsiden eller bunden af modellen, så hvorfor bygge den. Derudover bør man benytte teknikker som f.eks. normal mapping til at fake detaljer i modellen uden at tilføje ekstra polygoner.

Hold styr på antallet af draw calls

Det er ikke kun din GPU der arbejder, når der renderes objekter på skærmen. Din CPU sørger bl.a. for at holde styr på, hvilke lyskilder der påvirker dit objekt, opsætning af shaders og sender instruktioner til grafikdriveren. Alt dette sker for hvert objekt i din scene som skal renderes, og kaldes for draw calls.

Hvis du f.eks. har en model af en stol, som er delt op i seks separate modeller (ryg, sæde, og ben), så vil CPUen være nødt til at forholde sig til hver del. Det vil derfor være langt billigere at kombinere de seks dele til en model, hvilket kun vil ses som et objekt for CPUen.

At kombinere objekter sammen kan både gøres manuelt af enten en grafiker eller programmør, men mange engines har også funktionalitet til at gøre det automatisk på runtime.

Når man kombinerer objekter på den måde, er det vigtigt at huske, at disse så også kun deler et materiale. Hvis du har et materiale for hvert ben, stol og ryg, så vil du ikke opleve nogen optimering i ydelsen, selvom du har kombineret objekterne til et.

Lys er dyrt!

Tænk derfor over om du kan skifte dit dynamiske lys ud med et ”bagt” lightmap i stedet for. Der er mange fordele ved at bruge et lightmap fremfor dynamisk lys. Det er bl.a. langt billigere og så ser det også bedre ud.

De fleste engines har et lighmapping-værktøj integreret, Unity benytter f.eks. Beast fra Autodest.

Ulempen ved lightmapping er, at det giver et statisk lys, og det vil derfor være nødvendigt at indsætte et dynamisk lys, hvis du ønsker at kaste en skygge fra f.eks. din spilkarakter.

Hvad kan spilleren egentlig se?

Din spilverden kan være stor og indeholde mange objekter, og det er derfor vigtigt at overveje, hvad din spiller egentlig kan se. Culling er en teknik, der sørger for at sortere de objekter fra, som spilleren alligevel ikke kan se fra en given vinkel, og derved sparer du GPU og CPU til at processere disse.

En anden teknik, som også benyttes i forhold til, hvad spilleren kan se, er et Level of Detail(LOD) system. Her laver man to-tre forskellige kvalitetsversioner af sine 3D-modeller, og LOD systemet sørger for at skifte mellem de forskellige modeller i forhold til spillerens position.

Når spilleren er tæt på objektet, vil systemet vælge højkvalitetsversionen af modellen, men når spilleren går væk fra modellen, vil den skifte til en lavere version, da spilleren alligevel er for langt væk til at se detaljerne.

Ligesom med lightmapping, så har de fleste engines værktøjer integreret til at hjælpe med at opsætte et korrekt culling- og LOD-system for dit spil.

Brug en profiler

Der er rigtig mange faktorer, der kan give en dårlig ydelse for dit spil, og mit sidste råd er derfor at bruge en profiler til at finde frem til de steder, hvor du kan få mest ud af at optimere.

Her kan du bl.a. se udviklingen af antal draw calls, hukommelsesforbrug, og hvor meget tid din CPU bruger på rendering.

Anders Tankred Holms billede

Kommentarer (4)

Nicolai Willems

Hej Anders.

Først og fremmest tak for en god artikel, med udvikler relevant indhold.
Jeg er selv web udvikler, og ser mange af lignende ting. Jeg tror spil verdenen kan lære os andre mange ting om performance.

Jeg blev lidt fanget af dit screenshot, hvilken profiler er det?

Mvh Nicolai Willems

Torben Mogensen

En anden meget brugt teknik er, at udnytte, at mange polygoner kun kan ses fra den ene side, idet den anden side vender ind i en lukket figur. Hvis man f.eks. bygger en terning af seks kvadrater, så vil de allesammen kun kunne ses fra ydersiden af terningen.

Hvis man sætter en normalvektor på hver polygon, kan man se om den vender mod seeren eller væk fra. Hvis den vender væk fra, behøver man ikke at tegne polygonen, da den alligevel ikke kan ses.

Det klassiske spil Elite brugte dette som dels optimering og dels til at undgå at vise kanter, der ellers ville være skjult, i sin wireframe rendering. Af samme årsag var alle objekter i spillet konvekse, så en kant enten var helt synlig eller slet ikke synlig. Det forenklede renderingen betragteligt. Man kunne se, at der blve brugt en forenklet model, når to objekter passerede hinanden, da man kunne se det bageste igennem det forreste.

Flere (blandt andet Intel) har argumenteret for, at man i stedet for polygonrendering burde gå over til raytracing. Pointen er, at når antallet af objekter bliver meget stort, så overhaler raytracing polygonrendering i hastighed. Desuden er mange lys- og spejlingseffekter langt enklere at lave med raytracing, og raytracing håndterer ikke-flade objekter (kugler, cylindre, kegler, bezierkurver osv.) meget bedre end polygonsystemer, der skal f.eks. skal opdele en kugle i mange polygoner, før den ser troværdig ud. Derudover er level of detail og objekter bag seeren mere eller mindre automatisk håndteret.

Nutidens grafikprocessorer er optimeret til polygonrendering, så der skal nok nye grafikprocessorer til, før det kan betale sig. Men det kommer nok.

Michael Peters

Tak Anders for dit indlæg.

En stor del af vores business handler om 3D modeller og denne artikel er hvad vi til dagligt slås med, men det er rart at Unity er med her på denne blog, for Unity spilmotoren er rigtig spændende når man som vi, skal udvikle mobiltelefon spil.

Log ind eller opret en konto for at skrive kommentarer

IT Businesses