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

Opengl 如何使用纹理缓冲区读取单个整数而不是vec4,opengl,texture2d,Opengl,Texture2d,我有一个工作代码,从纹理缓冲区读取着色器中的vec4值 在客户端,我创建了一个位移向量缓冲区: vec4 vector1 : vec4(x1, y1, z1, w1); vec4 vector2 : vec4(x2, y2, z2, w2); vec4 vector3 : vec4(x3, y3, z3, w3); .. 然后我创建一个顶点缓冲区,其中包含向量1、向量2、向量3 接下来,我创建一个纹理,并使用以下方法将上面的缓冲区绑定到它: glTexBuffer(GL_TEXTURE_BUF

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

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

vec4 vector1 : vec4(x1, y1, z1, w1);
vec4 vector2 : vec4(x2, y2, z2, w2);
vec4 vector3 : vec4(x3, y3, z3, w3);
..
然后我创建一个顶点缓冲区,其中包含向量1、向量2、向量3

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

glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferID);
我选择GL_RGBA32F是因为x1、y1、z1、w1等都是浮动的

在着色器中,我可以使用以下方法获取各个向量:

vec4 vector1 = texelFetch(samplerObj, 0);
vec4 vector2 = texelFetch(samplerObj, 1);
.
.
但是,现在假设我的位移向量不是vec4,而是一个整数。 i、 e

有人能告诉我相应的格式是什么吗? 是吗

另外,如何在着色器中使用texelFetch获取值? 是吗


我很困惑,因为texelFetch应该返回一个包含4个分量的texel,所以我必须使用结果的红色分量吗?

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

除了
samplerBuffer
之外,您还需要
usamplerBuffer

如果您在内部格式为
R32UI
samplerBuffer
上执行
texelFetch
,则如上表所述,将返回一个uvec4,其中返回的组件将包含以下值:
uvec4(R,0,0,1)

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

int vector1 = texelFetch(samplerObj, 0).r;
此旋转遮罩将返回由
texelFetch
返回的uvec4的R分量,并执行从
uint
int
的隐式转换。从语义上讲,将标量值命名为向量也没有意义

你真正想要的是

uint displacement = texelFetch(samplerObj, 0).r;
其中,
samplerObj
是一个
usamplerBuffer

EDIT:为了澄清,
texelFetch
将始终返回一个gvec4,其中g将简单地按空(固定和浮点格式)、i或u返回。矢量的填充方式取决于缓冲区纹理的内部格式。如果选择R32F,将得到一个非规范化的vec4(R,0,0,1),对于RGBA16,将得到一个规范化的vec4(R,G,B,a)


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

我不知道samplerBuffers的情况,但对于image_load_store,内部格式必须与layout()语句匹配,当调用imageLoad()时,它总是返回一个vec4/uivec4/ivec4等。如果它没有4个组件,则忽略其余组件,如您所说,只需读取.r即可。我只是在这里猜测,但这可能意味着最好以16字节块读取。@jozxyqk:对于非图像统一布局,没有格式限定符。@thokra这就是我以“我不知道采样缓冲区”开头的原因。我正试图提供类似的知识。它并不完全匹配,但可能有一些重叠。texelFetch是否以4字节的步幅对内部格式为GL_R32UI的usamplerbuffer进行隐式索引,并保留rgba的gba未定义?我不知道。@jozxyqk:如果您使用的采样器与内部格式不匹配,则纹理查找函数返回的值将是未定义的。因此,对于浮点格式,您使用采样器*,对于非规范化的int和uint格式,您分别使用isampler*或usampler*。我相信大部分问题都是指texelFetch始终返回4分量向量这一事实。如果使用texelFetch(samplerObj,0).r,则给出第一个元素。texelFetch(samplerObj,1).r给你第二个元素还是第五个元素?这个问题的答案是否取决于内部格式?例如,如果内部格式为GL_R32UI,则返回第二个元素并且GL_RGBA32UI导致返回第五个无符号int是可以理解的。Image_load_store需要一个显式布局声明,它与samplerBuffer类似,但是隐式的吗?@jozxyqk:请参阅我的编辑。您将获得数据存储中的第一个和第二个元素。将texcoord增加1将始终为您提供下一个元素,因为缓冲区纹理基本上由1D数组(缓冲区对象的数据存储)支持。
int vector1 = texelFetch(samplerObj, 0);
int vector1 = texelFetch(samplerObj, 0).r ?
int vector1 = texelFetch(samplerObj, 0);
int vector1 = texelFetch(samplerObj, 0).r;
uint displacement = texelFetch(samplerObj, 0).r;