Estou no processo de descobrir como empacotar todas as informações de que preciso para um Renderizador adiado fisicamente baseado em um G-Buffer sem usar um obsceno quantidade de alvos de renderização.

O que eu tenho até agora são 4 vetores de 3 partes:

  • Albedo / Diffuse
  • Normal
  • Tangente
  • Posição

E 4 componentes individuais

  • Metálico
  • Rugosidade
  • Altura
  • Oclusão de ambiente

Uma abordagem ingênua é agrupar um dos componentes únicos no canal alfa (quarto) com um dos vetores de 3 partes, que é minha linha de investigação atual. No entanto, dado que quatro alvos de renderização de ponto flutuante de precisão total de 4 canais não são pequenos, entendo que seja comum usar meia precisão e representações ainda menores para ter mais consciência da memória.

O que estou perguntando é: quais componentes posso reduzir com segurança a precisão sem perder qualidade e em quanto?

Resposta

Em primeiro lugar, você não precisa de nenhuma posição no G-buffer. A posição de um pixel pode ser reconstruída a partir do buffer de profundidade , conhecendo a configuração da câmera e a posição xy do espaço da tela do pixel. Assim, você pode se livrar todo o buffer.

Além disso, normalmente você não precisa de vetores tangentes no G-buffer. Eles são necessários apenas para converter mapas normais do espaço tangente e para mapeamento de paralaxe; isso seria feito durante a passagem de preenchimento do G-buffer (quando você tem tangentes da malha que está renderizando), e o G-buffer só armazenar normais no mundo ou visualizar o espaço.

Propriedades de materiais como cores, rugosidade e metálico são geralmente apenas valores de 8 bits no G-buffer, uma vez que “se originam de texturas de 8 bits. O mesmo para AO.

A altura também não é necessária no G-buffer, a menos que você vá fazer algum tipo de combinação multi-passagem que dependa disso, mas se você precisar, provavelmente 8 bits é o suficiente para isso também.

Os normais podem se beneficiar ao serem armazenados como valores de 16 bits em vez de 8 bits. Meia-flutuação está bem, mas o ponto fixo de 16 bits é ainda melhor, pois oferece uma precisão mais uniforme em todas as orientações (meia-flutuação é mais preciso perto dos eixos e perde alguma precisão fora deles). Além disso, você pode cortá-los de 3 componentes para 2 usando o mapeamento octaédrico .

Então, no final do dia, um mínimo G-buffer pode ser semelhante a:

  • Cor do material + metálico: RGBA8
  • Espaço-mundo octaédrico normal + rugosidade + AO: RGBA16

e isso é tudo! Apenas 12 bytes por pixel.

Alternativamente, você poderia usar um buffer RG16 para os normais e mover rugosidade + AO para um buffer separado de 8 bits. Isso lhe daria algum espaço para crescer, caso você precise de mais componentes G-buffer de tamanhos de 8 ou 16 bits.

Comentários

  • Além disso, metalicidade costuma ser um valor binário e, supondo que você não usará gradientes de rugosidade (para ver o impacto da precisão reduzida), poderá armazenar metalicidade e rugosidade em um único canal de 8 bits (1 bit para metalosidade e 7 para rugosidade).

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *