¿Cómo puedo almacenar valores positivos y negativos en una textura?

Dec 03 2020

Estoy creando un programa en el que estoy usando la GPU para hacer cálculos (a través de sombreadores de fragmentos) y necesito almacenar valores firmados dentro de las texturas.

Mi textura se inicializa con GL_FLOAT, así:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);

Y por lo que entiendo sobre opengl, los texels individuales deben estar en el rango [0,1] cuando se usa GL_FLOAT (cuando experimenté con glClear, mis valores se recortarían a este rango). Entonces, lo que he estado haciendo hasta ahora es escalar mis valores al rango [-1,1] basado en su rango real, luego convertirlo a [0,1] antes de volver a escribirlo en la textura. El siguiente sombreador que necesita trabajar con los datos lee el valor de texel y lo mueve a [-1,1] antes de continuar y así sucesivamente ...

Mi pregunta es, ¿es esta la forma correcta de lidiar con los valores negativos? Estoy bastante seguro de que las conversiones repetidas están haciendo que se acumulen errores de fp, lo que obviamente no es bueno para la precisión.

Gracias

Respuestas

1 httpdigest Dec 03 2020 at 15:04

Ver también: Diferencia entre formato y formato interno

El formato interno (tercer parámetro de glTexImage2D) decide cómo la GPU almacena e interpreta esos valores, no el parámetro de tipo de glTexImage2D(penúltimo parámetro). Ese parámetro decide cómo debe interpretar el controlador la memoria del lado del cliente / host al cargar la textura, que actualmente no usa nullptr.

Puede utilizar el formato interno de tamaño de coma flotante firmado de 8 bits GL_RGBA8_SNORMo de 16 bits o de coma flotante de GL_RGBA16F32 bits para la textura.GL_RGBA32F

Por lo general, siempre se debe usar un tamaño de formato interno a ser explícito en lo que quiere y obtener.

Vea la tabla en: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml

Entonces, si solo necesita una resolución de 8 bits y valores en el rango [-1, 1], entonces puede usar:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

El penúltimo argumento es realmente irrelevante, porque no estamos cargando ningún dato de texto a la textura.