在片段着色器中纹理错误的值

时间:2015-08-17 20:19:36

标签: c++ opengl glsl

我将自定义数据加载到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语法的值时,它返回0.25而不是1.如何修复缩放问题?

if (texture(grammar, vec2(0,0) == 0.25) {
    FragColor = vec4(0,1,0,1);
} else
{
    FragColor = vec4(1,0,0,1);
}

1 个答案:

答案 0 :(得分:3)

默认情况下,纹理插值设置为以下值:

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)像素[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