Sto cercando di capire come impacchettare tutte le informazioni di cui ho bisogno per un renderer differito basato fisicamente in un G-Buffer senza usare un osceno quantità di target di rendering.

Quello che ho finora è 4 vettori in 3 parti:

  • Albedo / Diffuse
  • Normale
  • Tangente
  • Posizione

E 4 singoli componenti

  • Metallico
  • Rugosità
  • Altezza
  • Occlusione ambientale

Un approccio ingenuo consiste nel raggruppare uno dei singoli componenti nel canale alfa (quarto) con uno dei vettori in 3 parti, che è la mia attuale linea di indagine. Tuttavia, dato che quattro target di rendering in virgola mobile a piena precisione a 4 canali non sono piccoli, capisco che sia comune usare la metà della precisione e rappresentazioni ancora più piccole per essere più attenti alla memoria.

Quello che sto chiedendo è: su quali componenti posso ridurre la precisione senza perdere qualità e di quanto?

Risposta

Prima di tutto, non hai affatto bisogno di una posizione nel G-buffer. La posizione di un pixel può essere ricostruita dal depth buffer , conoscendo la configurazione della fotocamera e la posizione xy dello spazio sullo schermo del pixel. Così puoi sbarazzartene lintero buffer.

Inoltre, normalmente non hai bisogno di vettori tangenti nel G-buffer. Sono necessari solo per convertire le mappe normali dallo spazio tangente e per la mappatura della parallasse; questi sarebbero fatti durante il passaggio di riempimento del G-buffer (quando hai tangenti dalla mesh che stai “ri rendering), e il G-buffer lo farebbe solo memorizzare le normali nel mondo o visualizzare lo spazio.

Le proprietà dei materiali come colori, rugosità e metallo sono generalmente solo valori a 8 bit nel G-buffer, poiché “provengono da trame a 8 bit. Lo stesso per AO.

Anche laltezza non è necessaria nel G-buffer a meno che tu non stia facendo una sorta di miscelazione multi-pass che dipende da essa, ma se ne hai bisogno, 8 bit probabilmente sono abbastanza anche per questo.

Le normali possono trarre vantaggio dallessere memorizzate come valori a 16 bit invece che a 8 bit. Il mezzo float va bene, ma il punto fisso a 16 bit è ancora meglio, in quanto ti dà una precisione più uniforme su tutti gli orientamenti (il mezzo float è più preciso vicino agli assi e perde un po di precisione lontano da essi). Inoltre, puoi tagliarli da 3 componenti a 2 utilizzando la mappatura ottaedrica .

Quindi, alla fine della giornata, un minimo G-buffer potrebbe avere il seguente aspetto:

  • Colore materiale + metallico: RGBA8
  • Normale spazio-mondo ottaedrico + rugosità + AO: RGBA16

e questo è tutto! Solo 12 byte per pixel.

In alternativa, potresti usare un buffer RG16 per le normali e spostare rugosità + AO in un buffer a 8 bit separato. Questo ti darebbe un po di spazio per crescere se alla fine dovessi avere bisogno di più componenti G-buffer di dimensioni a 8 o 16 bit.

Commenti

  • Inoltre, metalness è spesso un valore binario e, supponendo che non si utilizzino gradienti di rugosità (in modo da vedere limpatto di una precisione ridotta), è possibile memorizzare la metallicità e la rugosità in un singolo canale a 8 bit (1 bit per la metallicità e 7 per la rugosità).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *