内部格式为 GL_RGBA8 的纹理在片段着色器中显示为 float

问题描述

我用这个调用创建了一个纹理:

glTexImage2D(GL_TEXTURE_2D,GL_RGBA8,w,h,GL_RGBA,GL_UNSIGNED_BYTE,0);

我用深灰色渲染纹理:

glColor3ub(42,42,42);
glBegin()...

现在我使用自定义着色器将此纹理渲染到后台缓冲区。在片段中,我像这样访问纹理:

#version 130
#extension GL_EXT_gpu_shader4 : require
uniform usampler2D text_in;

并使用以下方法获取数据:

uvec4 f0 = texture(text_in,gl_TexCoord[0].st);

我希望 f0[0] 中的值是 42u,但它是 1042852009u,恰好是

float x = 42/255.0f;
unsigned i = *reinterpret_cast<int*>(&x);

我做错了什么?我想使用整数纹理,以便我在片段着色器中可以将像素值与精确的整数值进行比较。我知道渲染到纹理效果很好,因为如果我在没有自定义着色器的情况下将纹理渲染到后台缓冲区,我会按预期得到 42 灰色。

解决方法

RGBA8 格式是一种未签名的 normalized 格式。因此,当您读取/写入它时,它被视为浮点格式,其值限制在 [0,1] 范围内。归一化值基本上只是压缩的浮点数。

如果您想要一个 unsigned integer format,您正在寻找 GL_RGBA8UI。请注意,在使用 GL_RGBA_INTEGER 时,您还必须在 pixel transfer format field 中使用 glTexImage2D