Jag är i färd med att ta reda på hur jag packar all information jag behöver för en fysiskt baserad uppskjuten renderare i en G-buffert utan att använda en obscen mängden renderingsmål.

Det jag har hittills har är 4 tredelade vektorer:

  • Albedo / Diffuse
  • Normal
  • Tangent
  • Position

Och fyra enskilda komponenter

  • Metallic
  • Grovhet
  • Höjd
  • Omgivande ocklusion

Ett naivt tillvägagångssätt är att bunta en av de enskilda komponenterna i alfa (fjärde) kanalen med en av tredelade vektorer, vilket är min nuvarande undersökningslinje. Men med tanke på att fyra 4-kanals full precision flytande punkt renderingsmål inte är små förstår jag att det är vanligt att använda halv precision och ännu mindre representationer för att vara mer minnesmedvetna.

Det jag frågar är: vilka komponenter kan jag säkert minska precisionen utan att tappa kvalitet, och hur mycket?

Svara

Först och främst behöver du inte position i G-bufferten alls. En pixels position kan rekonstrueras från djupbufferten , med kännedom om kamerainställningen och pixelns skärmutrymme xy-position. Så att du kan bli av med hela bufferten.

Dessutom behöver du vanligtvis inte tangentvektorer i G-bufferten heller. De behövs bara för att konvertera normala kartor från tangentutrymme och för parallaxmappning. Dessa skulle göras under G-buffertfyllningskortet (när du har tangenter från nätet som du återger), och G-bufferten bara lagra normaler i världen eller visa utrymme.

Materialegenskaper som färger, grovhet och metall är vanligtvis bara 8-bitars värden i G-bufferten, eftersom de kommer från 8-bitars texturer. Samma för AO.

Höjd behövs inte heller i G-bufferten såvida du inte kommer att göra någon form av multi-pass-blandning som beror på den, men om du behöver det är 8 bitar antagligen tillräckligt för det också.

Normaler kan dra nytta av att lagras som 16-bitars värden snarare än 8-bitars. Half-float är okej, men 16-bitars fixpunkt är ännu bättre, eftersom det ger dig mer enhetlig precision över alla riktningar (halv-float är mer exakt nära axlarna och förlorar lite precision bort från dem). Dessutom kan du klippa dem från 3 komponenter ner till 2 med oktaedrisk kartläggning .

Så, i slutet av dagen, en minimal G-buffert kan se ut:

  • Materialfärg + metallic: RGBA8
  • Oktahedral världsutrymme normal + ojämnhet + AO: RGBA16

och det är allt! Endast 12 byte per pixel.

Alternativt kan du använda en RG16-buffert för de normala och flytta grovhet + AO till en separat 8-bitars buffert. Det skulle ge dig lite utrymme att växa om du så småningom behöver fler G-buffertkomponenter i antingen 8-bitars eller 16-bitarsstorlekar.

Kommentarer

  • Även metallitet är ofta ett binärt värde, och förutsatt att du inte använder grovhetsgradienter (för att se effekten av minskad precision) kan du lagra metall och grovhet i en enda 8-bitars kanal (1 bit för metallhet och 7 för grovhet).

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *