8

我有一个工作代码,我正在从纹理缓冲区读取着色器中的 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,而是一个整数。IE

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 个组件的 texel,所以我必须使用结果的红色组件吗?

4

1 回答 1

9

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

除了 asamplerBuffer你还需要一个usamplerBuffer.

如果您使用内部格式执行 a texelFetchon a ,如上述表格中指定的那样,将返回一个 uvec4 ,其中返回的组件将包含以下值:.samplerBufferR32UIuvec4(R, 0, 0, 1)

int vector1 = texelFetch(samplerObj, 0);

这将导致编译时错误,因为没有从uvec4to的隐式转换int

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

这个 swizzle-mask 将返回由返回的 uvec4 的 R 分量,并执行从totexelFetch的隐式转换。从语义上讲,将标量值命名为vector也是没有意义的。;)uintint

你真正想要的是

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

哪里samplerObjusamplerBuffer

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

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

于 2013-09-06T09:06:54.627 回答