opengl - 精确控制GLSL中的纹理位

标签 opengl glsl shader bit-manipulation textures

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

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

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

最佳答案

自OpenGL 3开始,GLSL着色器内的整数和位操作就受支持(因此,它可以在DX10类硬件上使用,如果可以了解更多信息)。因此,您可以在着色器中自行进行位维护。

但是使用整数是一回事,使它们脱离纹理是另一回事。标准的OpenGL纹理格式(您可能习惯过)要么直接存储浮点数(如GL_R16F),要么存储规范化的定点值(如GL_R16,实际上是未初始化的整数;)),但从中读取(使用texturetexelFetch或(无论是哪种值)都会使您在着色器中 float 值,从而无法轻松或可靠地推导出内部存储的整数的原始位模式。

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

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

中央处理器:

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;

关于opengl - 精确控制GLSL中的纹理位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14961098/

相关文章:

c++ - Opengl 透明部分呈现黑色

java - LWJGL GLSL 着色器定向光呈现由内而外的效果

c++ - 绘制线条时关闭openGL中的颜色插值

c++ - 引起问题的纹理

c++ - 顶点着色器中的统一采样器2D

c - OpenGL 在 OS X 上包含指令

THREE.JS UV 贴图覆盖整个 THREE.BufferGeometry

glsl - 尝试将 GLSL 玻璃着色器移植到Processing 3.0

three.js - 如何在着色器中为纹理添加雾(THREE.JS R76)

c++ - GPU 上的 HSL 图像调整