如何使用纹理缓冲区来读取单个整数而不是vec4

时间:2013-09-06 06:57:43

标签: opengl texture2d

我有一个工作代码,我在纹理缓冲区中从着色器中读取vec4值。

在客户端,我创建了一个位移矢量缓冲区:

vec4 vector1 : vec4(x1, y1, z1, w1);
vec4 vector2 : vec4(x2, y2, z2, w2);
vec4 vector3 : vec4(x3, y3, z3, w3);
..

然后我创建一个包含vector1,vector2,vector3 ....的顶点缓冲区。

接下来,我创建一个纹理并使用以下方法将上面的缓冲区绑定到它:

glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferID);

我选择了GL_RGBA32F,因为x1,y1,z1,w1等都是浮点数。

在着色器中

我可以使用以下方法获取各个向量:

vec4 vector1 = texelFetch(samplerObj, 0);
vec4 vector2 = texelFetch(samplerObj, 1);
.
.

但是,现在假设我的位移矢量不是vec4,而是一个整数。 即

int vector1 = x1; //(int is 32 bit unsigned)
int vector2 = x2; //(int is 32 bit unsigned)
有人可以告诉相应的internalFormat会是什么? 是吗

glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, bufferID);

我还将如何在着色器中使用texelFetch获取值? 是吗

int vector1 = texelFetch(samplerObj, 0);

int vector1 = texelFetch(samplerObj, 0).r ?

我很困惑因为texelFetch应该返回一个有4个组件的纹素,所以我必须使用结果的红色组件吗?

1 个答案:

答案 0 :(得分:7)

您已经提到了无符号整数的正确大小的内部格式:R32UI。允许的格式在表8.15 中列举,可在OpenGL 4.4核心配置文件规范的第8.9节中找到。请注意,在具有上述内部格式的缓冲区纹理上使用texelFetch时,缓冲区存储的内容不会被标准化!这意味着,在进行查找时,您不会获得[0,1]范围内的值,但是在[0,2 ^(n-1)]范围内。

而不是samplerBuffer,您还需要usamplerBuffer

如果texelFetch的{​​{1}}内部格式为samplerBuffer,如上述表格所示,将返回一个uvec4,返回的组件将包含以下值:R32UI

uvec4(R, 0, 0, 1)

这将导致编译时错误,因为没有从int vector1 = texelFetch(samplerObj, 0); uvec4的隐式转换。

int

此swizzle-mask将返回int vector1 = texelFetch(samplerObj, 0).r; 返回的uvec4的R分量,并执行从texelFetchuint的隐式转换。从语义上讲,将标量值命名为 vector 也没有意义。 ;)

你真正想要的是像

int

其中uint displacement = texelFetch(samplerObj, 0).r; samplerObj

编辑:为了澄清,usamplerBuffer将始终返回gvec4 - 其中 g 将只是空(固定和浮点格式), i u 。填充向量的方式取决于缓冲区纹理的内部格式。如果你选择R32F,你会得到一个非标准化的vec4(R,0,0,1),对于RGBA16你会得到一个标准化的vec4(R,G,B,A)。

为避免进一步混淆:使用单分量格式时,不为4分量向量分配内存!他们只是在查找时扩展到了gvec4!