opengl glsl shader bit-manipulation textures

opengl - Control preciso sobre los bits de textura en GLSL



shader bit-manipulation (1)

Las manipulaciones enteras y de bits dentro de sombreadores GLSL son compatibles desde OpenGL 3 (por lo tanto, presente en hardware de clase DX10, si eso le dice más). Así que puedes hacer esta centralización de bits por tu cuenta dentro del sombreador.

Pero trabajar con enteros es una cosa, sacarlos de la textura es otra. Los formatos de textura estándar de OpenGL (a los que puede estar acostumbrado) almacenan flotadores directamente (como GL_R16F ) o valores de punto fijo normalizados (como GL_R16 , efectivamente enteros para los no iniciados;)), pero leyendo de ellos (usando texture , texelFetch o lo que sea) generará valores flotantes en el sombreador, del cual no se puede deducir fácilmente o confiablemente el patrón de bits original del entero almacenado internamente.

Entonces, lo que realmente necesita usar es una textura entera, que también requiere OpenGL 3 (o tal vez la extensión GL_EXT_texture_integer , pero el hardware que lo soporte probablemente tendrá GL3 de todos modos). Por lo tanto, para su textura necesita usar un formato interno entero real, como por ejemplo GL_R16UI (para un entero sin signo de 16 bits de 1 componente) en contraste con los formatos de punto fijo habituales (como, por ejemplo, GL_R16 para un normalizado [0,1] - color con precisión de 16 bits).

Y luego en el sombreado necesita usar un tipo de muestreador entero, como por ejemplo usampler2D para una textura 2D entera sin signo (y también isampler... para las variantes con signo) para obtener un entero sin signo de su texture o llamadas de texelFetch :

UPC:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, ..., GL_R, GL_UNSIGNED_SHORT, data);

GPU:

uniform usampler2D tex; ... uint value = texture(tex, ...).r; bool b1 = (value&0x8000) == 0x8000, b2 = (value&0x4000) == 0x4000; uint i1 = (value>>4) & 0x3FF, i2 = value & 0xF;

Estoy tratando de implementar un esquema transversal octree usando OpenGL y GLSL, y me gustaría mantener los datos en texturas. Si bien hay una gran selección de formatos para usar en los datos de texturas (flotantes y enteros de diferentes tamaños), tengo algunos problemas para determinar si hay una manera de tener un control más preciso sobre los bits y así lograr una mayor eficiencia y un almacenamiento compacto. Esto podría ser un problema general, no solo aplicando a OpenGL y GLSL.

Como un simple ejemplo de juguete, digamos que tengo un texel que contiene un entero de 16 bits. Quiero codificar dos booleanos de 1 bit cada uno, un valor entero de 10 bits y luego un valor entero de 4 bits en este texel. ¿Existe una técnica para codificar esto al crear la textura, y luego decodificar estos componentes cuando se muestrea la textura usando un sombreador GLSL?

Editar: parece que de hecho estoy buscando técnicas de manipulación de bits. Como parecen ser compatibles, estaré bien después de investigar un poco más.