片段着色器中的纹理错误值
Texture wrong value in fragment shader
我正在将自定义数据加载到 2D 纹理中 GL_RGBA16F:
glActiveTexture(GL_TEXTURE0);
int Gx = 128;
int Gy = 128;
GLuint grammar;
glGenTextures(1, &grammar);
glBindTexture(GL_TEXTURE_2D, grammar);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, Gx, Gy);
float* grammardata = new float[Gx * Gy * 4](); // set default to zero
*(grammardata) = 1;
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,Gx,Gy,GL_RGBA,GL_FLOAT,grammardata);
int grammarloc = glGetUniformLocation(p_myGLSL->getProgramID(), "grammar");
if (grammarloc < 0) {
printf("grammar missing!\n");
exit(0);
}
glUniform1i(grammarloc, 0);
当我在 GLSL 中读取 uniform sampler2D 语法的值时,它 returns 0.25 而不是 1。如何解决缩放问题?
if (texture(grammar, vec2(0,0) == 0.25) {
FragColor = vec4(0,1,0,1);
} else
{
FragColor = vec4(1,0,0,1);
}
默认情况下,纹理插值设置为以下值:
GL_TEXTURE_MIN_FILTER = GL_NEAREST_MIPMAP_LINEAR,
GL_TEXTURE_MAG_FILTER = GL_LINEAR
GL_WRAP[R|S|T] = GL_REPEAT
这意味着,如果屏幕上的纹理纹素和像素之间的映射不合适,硬件插值将为您进行插值。可以有两种情况:
显示的纹理比实际小:在这种情况下,在两个 mipmap 级别之间执行插值。如果没有生成 mipmap,这些将被视为 beeing 0,这可能导致 0.25。
纹理显示的比实际大(我认为这里会是这种情况):这里,硬件不在 mipmap 级别之间进行插值,而是在纹理中的相邻纹素之间进行插值。现在的问题是,纹理坐标中的 (0,0) NOT 是像素 [0,0] 的中心,而是它的左下角。
看看下面的图,它说明了纹理坐标是如何定义的(这里有 4 个纹素)
tex-coord: 0 0.25 0.5 0.75 1
texels |-----0-----|-----1-----|-----2-----|-----3-----|
如您所见,0 在纹理元素的边界上,而第一个纹理元素的中心位于 (1/(2 * |texels|))。
这对您来说意味着,当环绕模式设置为 GL_REPEAT 时,纹理坐标 (0,0) 将在纹素 [0,0]、[-1,0]、[- 1,-1], [0,-1]。由于 -1 == 127
(由于重复)并且除 [0,0] 之外的所有内容均为 0,因此导致
([0,0] + [-1,0] + [-1,-1] + [0,-1]) / 4 =
1 + 0 + 0 + 0 ) / 4 = 0.25
我正在将自定义数据加载到 2D 纹理中 GL_RGBA16F:
glActiveTexture(GL_TEXTURE0);
int Gx = 128;
int Gy = 128;
GLuint grammar;
glGenTextures(1, &grammar);
glBindTexture(GL_TEXTURE_2D, grammar);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, Gx, Gy);
float* grammardata = new float[Gx * Gy * 4](); // set default to zero
*(grammardata) = 1;
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,Gx,Gy,GL_RGBA,GL_FLOAT,grammardata);
int grammarloc = glGetUniformLocation(p_myGLSL->getProgramID(), "grammar");
if (grammarloc < 0) {
printf("grammar missing!\n");
exit(0);
}
glUniform1i(grammarloc, 0);
当我在 GLSL 中读取 uniform sampler2D 语法的值时,它 returns 0.25 而不是 1。如何解决缩放问题?
if (texture(grammar, vec2(0,0) == 0.25) {
FragColor = vec4(0,1,0,1);
} else
{
FragColor = vec4(1,0,0,1);
}
默认情况下,纹理插值设置为以下值:
GL_TEXTURE_MIN_FILTER = GL_NEAREST_MIPMAP_LINEAR,
GL_TEXTURE_MAG_FILTER = GL_LINEAR
GL_WRAP[R|S|T] = GL_REPEAT
这意味着,如果屏幕上的纹理纹素和像素之间的映射不合适,硬件插值将为您进行插值。可以有两种情况:
显示的纹理比实际小:在这种情况下,在两个 mipmap 级别之间执行插值。如果没有生成 mipmap,这些将被视为 beeing 0,这可能导致 0.25。
纹理显示的比实际大(我认为这里会是这种情况):这里,硬件不在 mipmap 级别之间进行插值,而是在纹理中的相邻纹素之间进行插值。现在的问题是,纹理坐标中的 (0,0) NOT 是像素 [0,0] 的中心,而是它的左下角。
看看下面的图,它说明了纹理坐标是如何定义的(这里有 4 个纹素)
tex-coord: 0 0.25 0.5 0.75 1
texels |-----0-----|-----1-----|-----2-----|-----3-----|
如您所见,0 在纹理元素的边界上,而第一个纹理元素的中心位于 (1/(2 * |texels|))。
这对您来说意味着,当环绕模式设置为 GL_REPEAT 时,纹理坐标 (0,0) 将在纹素 [0,0]、[-1,0]、[- 1,-1], [0,-1]。由于 -1 == 127
(由于重复)并且除 [0,0] 之外的所有内容均为 0,因此导致
([0,0] + [-1,0] + [-1,-1] + [0,-1]) / 4 =
1 + 0 + 0 + 0 ) / 4 = 0.25