内部格式为 GL_RGBA8 的纹理在片段着色器中显示为浮点数
Posted
技术标签:
【中文标题】内部格式为 GL_RGBA8 的纹理在片段着色器中显示为浮点数【英文标题】:texture with internal format GL_RGBA8 turns up in fragment shader as float 【发布时间】:2021-02-04 00:06:40 【问题描述】:我用这个调用创建了一个纹理:
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, w, h, 0,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 灰色。
【问题讨论】:
【参考方案1】:RGBA8
格式是无符号的normalized 格式。因此,当您读取/写入它时,它会被视为浮点格式,其值限制在 [0, 1] 范围内。归一化值基本上只是压缩的浮点数。
如果您想要unsigned integer format,您正在寻找GL_RGBA8UI
。请注意,使用glTexImage2D
时,还必须在pixel transfer format field 中使用GL_RGBA_INTEGER
。
【讨论】:
...纹理是透明的。glCheckFramebufferStatus
不报告任何错误。
glClearColor(0,1,0,1);glClear(GL_COLOR_BUFFER_BIT);
实际上按预期将纹理清除为[0,255,0,255]
,但glColor3ub
+ glBegin...
不会修改纹理。
现在可以了。我还需要一个自定义片段着色器来渲染整数纹理。但是我还是不知道glColor
设置的颜色是怎么从shader里面获取的,所以我用glGetUniformLocation
和glUniform4ui
来设置颜色。
@XPlatformer: "我仍然不知道如何从着色器内部访问 glColor 设置的颜色" 如果您正在使用整数纹理等功能,那么是时候抛弃兼容 GL 的世界了(比如glBegin/glColor
)并编写核心 OpenGL 的东西。以上是关于内部格式为 GL_RGBA8 的纹理在片段着色器中显示为浮点数的主要内容,如果未能解决你的问题,请参考以下文章