9

我正在尝试使用 OpenGL 和 GLSL 实现八叉树遍历方案,并希望将数据保存在纹理中。虽然纹理数据有多种格式可供选择(浮点数和不同大小的整数),但我很难确定是否有一种方法可以更精确地控制位,从而实现更高的效率和紧凑的存储。这可能是一个普遍的问题,不仅适用于 OpenGL 和 GLSL。

作为一个简单的玩具示例,假设我有一个包含 16 位整数的纹素。我想将两个每个 1 位的布尔值、一个 10 位整数值和一个 4 位整数值编码到这个纹素中。是否有一种技术可以在创建纹理时对其进行编码,然后在使用 GLSL 着色器对纹理进行采样时解码这些组件?

编辑:看起来我实际上正在寻找位操作技术。由于它们似乎受到支持,因此经过更多研究后我应该会没事的。

4

1 回答 1

4

自 OpenGL 3 起支持 GLSL 着色器中的整数和位操作(因此存在于 DX10 类硬件上,如果这能告诉您更多信息)。所以你可以在着色器中自己做这个位维护。

但是使用整数是一回事,让它们脱离纹理是另一回事。标准的 OpenGL 纹理格式(您可能习惯于)要么直接存储浮点数(如GL_R16F)或标准化的定点值(如GL_R16,对于未启动的有效整数;)),但从它们中读取(使用texturetexelFetch或其他)将净您在着色器中浮动值,您无法轻松或可靠地从中推断出内部存储整数的原始位模式。

所以你真正需要使用的是一个整数纹理,它也需要 OpenGL 3(或者可能是GL_EXT_texture_integer扩展,但支持它的硬件可能无论如何都会有 GL3)。因此,对于您的纹理,您需要使用实际的整数内部格式,例如GL_R16UI(对于 1 分量 16 位无符号整数),以对比通常的定点格式(例如GL_R16,对于标准化的 [0,1]-color 16 位精度)。

然后在着色器中,您需要使用整数采样器类型,例如usampler2D对于无符号整数 2D 纹理(同样适用于有符号变体),以便从您的or调用isampler...中实际获取无符号整数:texturetexelFetch

中央处理器:

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

显卡:

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;
于 2013-03-19T10:05:44.337 回答