Vic*_*and 9 opengl shader textures bit-manipulation glsl
我正在尝试使用OpenGL和GLSL实现八叉树遍历方案,并希望将数据保留在纹理中.虽然有很多种格式可用于纹理数据(不同大小的浮点数和整数),但我有一些麻烦,想知道是否有办法对位进行更精确的控制,从而实现更高的效率和紧凑的存储.这可能是一个普遍的问题,不仅适用于OpenGL和GLSL.
作为一个简单的玩具示例,假设我有一个包含16位整数的纹素.我想编码两个每个1位的布尔值,一个10位整数值,然后一个4位整数值到这个纹素.是否有一种技术可以在创建纹理时对其进行编码,然后在使用GLSL着色器对纹理进行采样时对这些组件进行解码?
编辑:看起来我实际上正在寻找位操作技术.由于它们似乎得到了支持,经过一些研究后我应该没问题.
自 OpenGL 3 起,就支持 GLSL 着色器内的整数和位操作(因此存在于 DX10 级硬件上,如果这能告诉您更多信息)。因此,您可以在着色器内自行完成此位维护。
但使用整数是一回事,将它们从纹理中取出又是另一回事。标准 OpenGL 纹理格式(您可能习惯的)要么直接存储浮点数(如GL_R16F
),要么存储标准化定点值(如GL_R16
,对于新手来说实际上是整数;)),但从它们中读取(使用texture
或texelFetch
其他方式)将获得净值。您在着色器中浮动值,您无法轻松或可靠地从中推断出内部存储的整数的原始位模式。
因此,您真正需要使用的是整数纹理,它也需要 OpenGL 3(或者可能是扩展GL_EXT_texture_integer
,但支持该功能的硬件无论如何都可能有 GL3)。因此,对于您的纹理,您需要使用实际的整数内部格式,例如GL_R16UI
(对于 1 分量 16 位无符号整数),与通常的定点格式(例如,GL_R16
对于归一化 [0,1]-颜色16 位精度)。
然后在着色器中,您需要使用整数采样器类型,例如usampler2D
对于无符号整数 2D 纹理(同样对于有符号变体),以实际从您的或调用isampler...
中获取无符号整数:texture
texelFetch
中央处理器:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, ..., GL_R, GL_UNSIGNED_SHORT, data);
Run Code Online (Sandbox Code Playgroud)
图形处理器:
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;
Run Code Online (Sandbox Code Playgroud)