What is the best grass asset for mobile?

Mobil Shader vs. Legacy Shader: Optimer din App

19/06/2022

Rating: 4.88 (14258 votes)

At udvikle spil eller interaktive applikationer til mobile enheder som Android byder på unikke udfordringer, især når det kommer til ydeevne. Mange udviklere støder på problemer med faldende billedhastighed (FPS), når de overfører deres projekter fra desktop til mobil. Et af de mest almindelige syndere er brugen af ressourcekrævende shaders, især den standard shader, der ofte bruges i udviklingsfasen.

How do I make a pixel shader work on a mobile device?
On mobiles you’re essentially fillrate bound (fillrate = screen pixels * shader complexity * overdraw), and over-complex shaders is the most common cause of problems. So use mobile shaders that come with Unity or design your own but make them as simple as possible. If possible simplify your pixel shaders by moving code to vertex shader.

Hvis du, ligesom mange andre, oplever, at din Android-app sakker bagud med kun 30-50 FPS, selv efter at have optimeret partikeleffekter med mobil shaders, er det tid til at se nærmere på dine almindelige 3D-objekter som kuber og sfærer. Du har måske læst, at standard shaderen er lig med 'døden' på mobile enheder, og det er en sandhed med modifikation. Men frygt ej, der findes løsninger! Spørgsmålet er nu: skal du vælge en shader fra 'Mobiles'-fanen eller en 'Legacy'-shader, især når du blot ønsker at justere farven på et objekt og understøtte et lightmap? Denne artikel vil dykke ned i de bedste fremgangsmåder for at optimere dine shaders og få din mobilapp til at køre silkeblødt.

Indholdsfortegnelse

Hvorfor Standard Shaders er et Problem på Mobil

Standard shaderen er utroligt alsidig og kraftfuld, men denne alsidighed kommer med en høj pris i form af ydeevne. Den er designet til at håndtere en bred vifte af visuelle effekter, herunder komplekse lysberegninger, refleksioner, refraktioner og materialegenskaber, som ofte ikke er nødvendige for simple objekter. På en desktop-PC med en dedikeret og kraftig GPU er dette sjældent et problem. Men mobile enheder har begrænsede ressourcer, og deres GPU'er er designet med energieffektivitet og varmeafledning for øje, hvilket betyder, at de har langt mindre båndbredde, lavere ALU-ydeevne og mindre teksturkraft sammenlignet med desktop-modparter.

Når en standard shader anvendes på selv simple objekter på mobil, udfører den unødvendigt mange beregninger per pixel. Dette fører til en høj overdraw og en stor belastning på GPU'ens fillrate, hvilket er antallet af pixels, GPU'en kan tegne til skærmen per sekund. Resultatet er et drastisk fald i FPS, da GPU'en simpelthen ikke kan følge med.

Forstå Ydeevne på Mobile Enheder

For at optimere effektivt er det vigtigt at forstå, hvor flaskehalsene typisk opstår på mobile enheder. Ydeevnen er ofte bundet af fillrate, pixel- og geometrisk kompleksitet (antal polygoner/vertices).

GPU Fokus: Fillrate og Overdraw

På mobile enheder er du typisk begrænset af fillrate, som er et produkt af skærmpixels, shader-kompleksitet og overdraw. Over-komplekse shaders er den mest almindelige årsag til problemer. Overdraw opstår, når pixels tegnes flere gange på samme sted, f.eks. når transparente objekter overlapper, eller når komplekse shaders tegner mange lag. For at bekæmpe dette:

  • Brug simple mobil shaders, der følger med Unity, eller design dine egne, men gør dem så enkle som muligt.
  • Hvis muligt, forenkle dine pixel shaders ved at flytte kode til vertex shaderen. Vertex shaders kører kun én gang per vertex, mens pixel shaders kører én gang per pixel, hvilket kan være mange tusinde gange mere.
  • Hvis reducerende teksturkvaliteten i dine kvalitetsindstillinger får spillet til at køre hurtigere, er du sandsynligvis begrænset af hukommelsesbåndbredde. Komprimer teksturer, brug mipmaps, reducer teksturstørrelse osv.
  • Undgå alpha-testing shaders (Cutout), medmindre det er absolut nødvendigt. Keep Transparent (alpha blend) skærmdækning til et minimum for at reducere overdraw.

CPU Fokus: Optimering af Proceskraft

Det er ofte tilfældet, at spil er begrænset af GPU'en, hvilket efterlader ubrugt CPU-kraft, især på flerkernede mobile CPU'er. Det kan derfor være fornuftigt at flytte noget arbejde fra GPU'en til CPU'en. Unity gør dette automatisk for visse opgaver som mesh skinning, batching af små objekter og partikelgeometriopdateringer.

Should I use a mobile shader or a legacy shader?
Legacy Standard Shader is going to perform than the current (PBR) shader. But for optimal efficiency you should use a mobile shader.
  • Sæt 'Static'-egenskaben på ikke-bevægelige objekter for at tillade interne optimeringer som statisk batching.
  • Brug okklusionsculling (occlusion culling) til at reducere antallet af objekter, der skal tegnes ved at skjule dem, der er uden for syne.
  • Undgå `FindObjectsOfType` og Unity's getter-egenskaber generelt, da de er meget langsomme.

Mobil Shaders vs. Legacy Shaders: Hvilken skal du vælge?

Når du står over for valget mellem 'Mobile' og 'Legacy' shaders, er det vigtigt at forstå deres historik og formål. 'Legacy' shaders er ældre shaders, der har eksisteret i Unity i lang tid. De er ofte enklere end standard shaderen og kan give et ydeevneboost sammenlignet med den. 'Mobile' shaders er derimod specifikt designet og optimeret til mobile platforme med fokus på maksimal ydeevne og minimalt ressourceforbrug. De er skrevet med tanke på de begrænsninger, mobile GPU'er har, og er ofte den mest sikre vej at gå for optimal mobil ydeevne.

Specifikt til Farve og Lightmaps

I dit tilfælde, hvor du kun ønsker at justere farven på et objekt og understøtte et lightmap, er valget ret ligetil. Standard shaderen er alt for kompleks. Du har flere gode muligheder blandt 'Mobile' og 'Legacy' shaders:

  • Mobile/Diffuse: Denne shader er en god all-rounder. Den understøtter en primær farve (albedo) og kan modtage per-vertex lys, samt tage lightmaps i betragtning. Den er langt mere simpel end standard shaderen og er et solidt valg for de fleste simple objekter.
  • Mobile/Unlit (Color eller Texture): Hvis du kun har brug for en solid farve og et lightmap, og ikke har brug for, at objektet reagerer på realtidslys ud over lightmap'et, er 'Mobile/Unlit' en ekstremt performant løsning. Den udfører næsten ingen lysberegninger og er derfor meget billig i ressourcer. Du kan vælge 'Mobile/Unlit (Color)' for en ren farve og 'Mobile/Unlit (Texture)' hvis du har en basefarve tekstur, som dit lightmap skal bages ovenpå.
  • Legacy/Diffuse: Ligner 'Mobile/Diffuse' i funktionalitet, men 'Mobile' versionen er ofte mere optimeret til de nyere mobile GPU-arkitekturer. Hvis du er i tvivl, vælg 'Mobile/Diffuse' eller 'Mobile/Unlit'.

For dine 'normale kuber, sfærer etc.' med forskellig farve og lightmap-understøttelse, er 'Mobile/Diffuse' sandsynligvis det bedste kompromis mellem visuel kvalitet og ydeevne. Hvis du kan undvære, at objekterne reagerer på dynamiske lyskilder (udover lightmap'et), vil 'Mobile/Unlit (Color)' eller 'Mobile/Unlit (Texture)' give den bedste ydeevne.

Sammenligning af Shader Typer for Mobil

For at give et klarere overblik, her er en sammenligningstabel over relevante shader-typer:

Shader TypeKompleksitetLys UnderstøttelseAlpha UnderstøttelseAnvendelse (Farve + Lightmap)Ydeevne (Mobil)
StandardHøjFuld (Realtidslys)JaDårligMeget Lav
Mobile/DiffuseMediumPer-vertex, LightmapJaGodMedium
Mobile/Unlit (Color/Texture)LavKun LightmapJaFremragendeMeget Høj
Legacy/DiffuseMediumPer-vertex, LightmapJaGodMedium

God Praksis for Shader Optimering

Udover at vælge den rigtige shader, er der mange andre optimeringer, du kan implementere for at forbedre ydeevnen på mobile enheder.

Materialer og Texturer

  • Få materialer: Hold antallet af materialer så lavt som muligt. Dette gør det lettere for Unity at batching objekter, hvilket reducerer draw calls.
  • Teksturatlasser: Brug teksturatlasser (store billeder, der indeholder en samling af delbilleder) i stedet for mange individuelle teksturer. Disse er hurtigere at indlæse, har færre state-skift og er batching-venlige.
  • Renderer.sharedMaterial: Brug Renderer.sharedMaterial i stedet for Renderer.material, hvis du bruger teksturatlasser og delte materialer. Renderer.material opretter en ny instans af materialet, hvilket er dyrt.
  • Teksturkomprimering: Komprimer teksturer, brug mipmaps og reducer teksturstørrelsen. Platformspecifik komprimering som ETC (for Android) og PVRTC (for iOS) er afgørende.
  • Undgå `Get/Set pixels`: Teksturer med 'Read/Write Enabled' (som tillader Get/Set pixels) fordobler hukommelsesfodaftrykket. Slå det fra, medmindre det er strengt nødvendigt.

Lys og Skygger

  • Lightmapping: Forward-rendered pixel lys er dyre. Brug lightmapping i stedet for realtidslys, hvor det er muligt. Dette bager lysinformationen ind i teksturer, hvilket er meget performant.
  • Juster pixel lysantal: I kvalitetsindstillingerne skal du justere antallet af pixel lys. Typisk bør kun det retningsbestemte lys være per pixel; alt andet bør være per vertex. Eksperimenter med 'Render Mode' for lys for at prioritere korrekt.
  • Reducér shader passes: Prøv at reducere det samlede antal shader passes (f.eks. skygger, pixel lys, refleksioner).
  • Undgå flere lys: Prøv at undgå situationer, hvor flere lys belyser et givet objekt.

Post-Processing og Partikler

  • Post-Processing: Post-processing effekter er dyre på mobiler, så brug dem med forsigtighed og kun når det er absolut nødvendigt.
  • Partikler: Reducer overdraw for partikler og brug de enkleste mulige shaders.

Avancerede Optimeringsteknikker

For at presse endnu mere ydeevne ud af dine apps, kan du overveje disse avancerede teknikker:

  • LOD (Level of Detail): Gør objekter enklere eller eliminer dem helt, efterhånden som de bevæger sig længere væk fra kameraet. Dette reducerer den geometriske kompleksitet for objekter, der ikke er i fokus.
  • Okklusionsculling: Dette er en proces, der forhindrer Unity i at tegne objekter, der er skjult bag andre objekter. Det kræver CPU-cyklusser at beregne, men kan spare en masse GPU-tid ved at reducere det samlede antal objekter, der skal tegnes.
  • Teksturkomprimering: Ud over de generelle råd, dyk ned i platformspecifikke komprimeringsformater. For Android er ETC/RGBA16 standard, men kan justeres afhængigt af GPU-leverandøren. ETC er bedst, hvor det er muligt. For iOS er PVRTC standard og fungerer godt i de fleste tilfælde.
  • Dynamiske Objekter og Asset Bundles: Hvis du har meget dynamisk indhold, kan Asset Bundles hjælpe med at administrere hukommelse og indlæsningstider. De caches på enheden og kan indlæses og aflæsses efter behov, hvilket holder den aktive hukommelsesfodaftryk nede. Husk at aflæsse ubrugte Asset Bundles og tilhørende aktiver for at undgå hukommelseslækager.

Ofte Stillede Spørgsmål

Hvad er forskellen på float, half og fixed i shaders?
Disse refererer til præcisionskvalifikatorer i GLSL ES (som bruges på mobile platforme). Når du bruger float, half eller fixed typer i HLSL (eller Cg), bliver de oversat til henholdsvis highp, mediump og lowp præcisionskvalifikatorer i GLSL ES. fixed (lowp) er den laveste præcision og den mest performante, mens float (highp) er den højeste og mest ressourcekrævende. Vælg den lavest mulige præcisionsformat for den bedste ydeevne.
Hvordan profilerer jeg bedst min mobilapp?
Brug Unity's Editor Profiler til at identificere flaskehalse. Hvis spillet kører hurtigere, når du reducerer skærmopløsningen, er du sandsynligvis begrænset af fillrate. Hvis CPU'en er flaskehalsen, kan du se på fysikberegninger (juster Time.fixedDeltaTime og Physics.solverIterationCount) og undgå tunge operationer som FindObjectsOfType. Test altid på faktiske enheder med profilering slået til.
Skal jeg bruge Renderer.material eller Renderer.sharedMaterial?
Brug altid Renderer.sharedMaterial, når du manipulerer et materiale, som deles mellem flere renderere, og du ønsker, at ændringerne skal påvirke alle instanser. Hvis du bruger Renderer.material, opretter Unity en ny instans af materialet, hvilket er dyrt i hukommelse og CPU og forhindrer batching. Kun brug Renderer.material, hvis du specifikt ønsker at ændre materialet kun for den ene renderer.
Hvad er Tile-Based Deferred Rendering (TBDR) og hvorfor er det vigtigt?
TBDR er en GPU-arkitektur, der bruges af mobile GPU'er som ImgTec PowerVR SGX og ARM Mali. I stedet for at tegne hele scenen på én gang, opdeler den skærmen i små 'fliser' (tiles) og behandler hver flise individuelt. Den skraverer (shader) kun de synlige pixels inden for hver flise. Dette reducerer behovet for hukommelsesbåndbredde og er meget energieffektivt, hvilket er en stor fordel på mobile enheder. Det betyder også, at mipmaps ikke altid er lige så nødvendige, og antialiasing kan være billigere. Ulempen er, at det kan være svært at få GPU-timing for et enkelt draw call, hvilket gør profilering mere udfordrende.
Hvad er Asset Bundles og hvordan hjælper de?
Asset Bundles er arkivfiler, der indeholder aktiver (modeller, teksturer, lyde osv.), som kan indlæses ved runtime. De er nyttige til at reducere den indledende app-størrelse, da aktiverne kan downloades efter behov. De hjælper også med hukommelsesstyring ved at give dig mulighed for at aflæsse aktiver, der ikke længere er i brug, hvilket forhindrer hukommelsesoverforbrug og potentielle nedbrud. Husk at aflæsse dem med AssetBundle.Unload(true/false) og rydde op i referencer med Resources.UnloadUnusedAssets().

Konklusion

Valget af den rigtige shader er en afgørende faktor for ydeevnen af din mobilapp. Ved at skifte fra den ressourcekrævende standard shader til en lettere løsning som 'Mobile/Diffuse' eller 'Mobile/Unlit' for dine simple 3D-objekter med farve og lightmaps, kan du opnå betydelige forbedringer i FPS. Husk, at mobiludvikling handler om kompromiser. Ved at implementere god praksis for shader- og ressourceoptimering, forstå de underliggende GPU- og CPU-begrænsninger og udnytte Unity's indbyggede værktøjer, kan du skabe flydende og engagerende oplevelser for dine brugere på tværs af et bredt spektrum af mobile enheder.

Hvis du vil læse andre artikler, der ligner Mobil Shader vs. Legacy Shader: Optimer din App, kan du besøge kategorien Teknologi.

Go up