Estoy en el proceso de averiguar cómo empaquetar toda la información que necesito para un Renderizador diferido basado en la física en un G-Buffer sin usar un obsceno cantidad de objetivos de render.

Lo que tengo hasta ahora son 4 vectores de 3 partes:

  • Albedo / Difuso
  • Normal
  • Tangente
  • Posición

Y 4 componentes individuales

  • Metálicos
  • Rugosidad
  • Altura
  • Oclusión ambiental

Un enfoque ingenuo es agrupar uno de los componentes individuales en el canal alfa (cuarto) con uno de los vectores de 3 partes, que es mi línea de investigación actual. Sin embargo, dado que cuatro objetivos de renderizado de punto flotante de precisión total de cuatro canales no son pequeños, entiendo que es común usar representaciones de precisión media e incluso más pequeñas para ser más conscientes de la memoria.

Lo que estoy preguntando es: ¿en qué componentes puedo reducir la precisión de manera segura sin perder calidad y en cuánto?

Respuesta

En primer lugar, no necesita posición en el búfer G en absoluto. La posición de un píxel se puede reconstruir a partir del búfer de profundidad , conociendo la configuración de la cámara y la posición xy del espacio de pantalla del píxel. De esta manera, puede deshacerse de todo ese búfer.

Además, normalmente tampoco necesitas vectores tangentes en el búfer G. Solo son necesarios para convertir mapas normales del espacio tangente y para el mapeo de paralaje; estos se realizarían durante la pasada de relleno del búfer G (cuando tienes tangentes de la malla que estás renderizando), y el búfer G solo almacenar normales en el mundo o en el espacio de visualización.

Las propiedades de los materiales como los colores, la rugosidad y el metal suelen ser valores de 8 bits en el búfer G, ya que «proceden de texturas de 8 bits. Lo mismo para AO.

La altura tampoco es necesaria en el búfer G a menos que vaya a realizar algún tipo de combinación de múltiples pasadas que dependa de ello, pero si lo necesita, probablemente 8 bits sea suficiente para eso también.

Los valores normales pueden beneficiarse si se almacenan como valores de 16 bits en lugar de 8 bits. Half-float está bien, pero el punto fijo de 16 bits es aún mejor, ya que le brinda una precisión más uniforme en todas las orientaciones (half-float es más preciso cerca de los ejes y pierde algo de precisión lejos de ellos). Además, puede cortarlos de 3 componentes a 2 usando mapeo octaédrico .

Entonces, al final del día, un mínimo G-buffer podría tener el siguiente aspecto:

  • Color del material + metálico: RGBA8
  • Espacio mundial octaédrico normal + rugosidad + AO: RGBA16

¡y eso es todo! Solo 12 bytes por píxel.

Alternativamente, puede usar un búfer RG16 para las normales y mover la rugosidad + AO a un búfer de 8 bits separado. Eso le daría algo de espacio para crecer si eventualmente necesita más componentes de búfer G de tamaños de 8 bits o 16 bits.

Comentarios

  • Además, metalness es a menudo un valor binario, y suponiendo que no usará gradientes de rugosidad (para ver el impacto de la precisión reducida), podría almacenar la metalidad y la rugosidad en un solo canal de 8 bits (1 bit para la metalidad y 7 para la rugosidad).

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *