Jeg er i ferd med å finne ut hvordan jeg skal pakke all informasjon jeg trenger for en fysisk basert utsatt renderer i en G-buffer uten å bruke en uanstendig mengden gjengivelsesmål.

Det jeg har så langt er 4 tredelte vektorer:

  • Albedo / Diffuse
  • Normal
  • Tangent
  • Position

Og 4 enkeltkomponenter

  • Metallic
  • Roughness
  • Høyde
  • Omgivende okklusjon

En naiv tilnærming er å pakke en av enkeltkomponentene i alfa (fjerde) kanal med en av de tre delte vektorene, som er min nåværende undersøkelseslinje. Men med tanke på at fire 4-kanals gjengivelsesmål for flytende punkt med full presisjon ikke er lite, forstår jeg at det er vanlig å bruke halv presisjon og enda mindre representasjoner for å være mer minnebevisst.

Det jeg spør om er: hvilke komponenter kan jeg trygt redusere presisjonen uten å miste kvaliteten, og med hvor mye?

Svar

Først og fremst trenger du ikke posisjon i G-bufferen i det hele tatt. Pikselens posisjon kan rekonstrueres fra dybdebufferen , med kunnskap om kameraoppsettet og pikselens skjermplass xy-posisjon. Så du kan bli kvitt hele bufferen.

Du trenger heller ikke tangentvektorer i G-bufferen. De er bare nødvendige for å konvertere normale kart fra tangentområdet, og for parallaks kartlegging; disse vil bli gjort under G-buffer fyllpasset (når du har tangenter fra nettet du gjengir), og G-bufferen ville bare lagre normaler i verden eller se rom.

Materielle egenskaper som farger, ruhet og metall er vanligvis bare 8-biters verdier i G-bufferen, siden de kommer fra 8-biters teksturer. Samme for AO.

Det er heller ikke behov for høyde i G-bufferen, med mindre du skal gjøre en slags multi-pass-blanding som avhenger av det, men hvis du trenger det, er sannsynligvis 8 bits nok til det også.

Normaler kan ha nytte av å bli lagret som 16-biters verdier i stedet for 8-bit. Half-float er greit, men 16-biters fixed-point er enda bedre, da det gir deg mer jevn presisjon på tvers av alle retninger (halv-float er mer presis nær aksene og mister litt presisjon vekk fra dem). Videre kan du kutte dem fra 3 komponenter ned til 2 ved hjelp av oktaedrisk kartlegging .

Så på slutten av dagen, et minimum G-buffer kan se ut som:

  • Materiellfarge + metallisk: RGBA8
  • Oktahedrisk verdensrom normal + ruhet + AO: RGBA16

og det er alt! Bare 12 byte per piksel.

Alternativt kan du bruke en RG16-buffer til det normale, og flytte ruhet + AO til en separat 8-bits buffer. Det vil gi deg noe rom for å vokse hvis du til slutt trenger flere G-bufferkomponenter i enten 8-biters eller 16-bitersstørrelser.

Kommentarer

  • Også metallitet er ofte en binær verdi, og forutsatt at du ikke vil bruke ruhetsgradienter (for å se effekten av redusert presisjon), kan du lagre metallhet og ruhet i en enkelt 8-bits kanal (1 bit for metallitet og 7 for ruhet).

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *