在Texture OpenGL中使用GL_LINEAR时的外部工件

时间:2018-01-24 14:35:22

标签: c++ opengl texture-mapping

我成功使用openGL中的纹理生成高度贴图。该数据的完整图片如下图所示。但是,当我在我的glTexParameteri(MinMag)中使用GL_LINEAR选项时,它会给我外部的工件。

这是我的glTexParameter

if (interpolate) {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else {
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

这是我的片段着色器代码

    "varying vec2 tex;\n"
    "uniform int colorSizeI;\n"
    "uniform vec4 colorTable[512];\n"
    "uniform vec2 minmaxZ;\n"
    "uniform vec3 backgroundColor;\n"
    "uniform sampler2D diffuse;\n"
    "uniform float transparency;\n"
    "void main() {\n"
    "   float color = texture2D(diffuse, tex).r;\n"
    "   float h = (color - minmaxZ[0])/(minmaxZ[1] - minmaxZ[0]);\n"
    "   float colorSizeF = float(colorSizeI);\n"
    "   int i = 0;\n"
    "   float j = 0.0f;\n"
    "   vec3 base;\n"
    "   if (color == 0.0f) {\n"
    "       base = vec3(0.0f, 0.0f, 0.0f);}\n"
    "   else if (color <= minmaxZ[0]) {\n"
    "       base = colorTable[0].xyz;}\n"
    "   else if (color >= minmaxZ[1]) {\n"
    "       base = colorTable[colorSizeI - 1].xyz;}\n"
    "   else { \n"
    "       while (h >= (j + 1.0f)/colorSizeF) {\n"
    "           i += 1;\n"
    "           j += 1.0f;}\n"
    "       base = mix(colorTable[i].xyz, colorTable[i+1].xyz, colorSizeF*(h - (j/colorSizeF)));}\n"
    "   gl_FragColor = vec4(base, transparency);\n"
    "}\n";

这是使用GL_Nearest时的图像(一切正常) using GL Nearest

这是使用GL_Linear时的图像(外部插值工件出来) using GL Linear

那么,有谁知道如何删除这些文物?

注意:当color = 0时,外部黑色也会考虑数据。

3 个答案:

答案 0 :(得分:1)

我假设您对纹理的包装当前是GL_REPEAT。你应该尝试另一个。

GL_MIRRORED_REPEAT或GL_CLAMP_TO_EDGE应该有效。

答案 1 :(得分:1)

错误是因为在colr表中从“null color”插值到实际颜色。简而言之:你做不到。这个概念被打破了。回到绘图板。

最简单的解决方案是没有空白颜色,仅将四边形限制为有效区域,并按照其他建议执行GL_CLAMP_TO_EDGE。

一种更棘手的方法是设置GL_NEAREST,然后在着色器中自己编写线性采样,使用tex加上一些偏移(曼哈顿距离应该没问题)对纹理进行采样,并在混合时跳过空白颜色(跳过部分)是您原始概念中缺少的东西)。棘手的部分是使偏移正确。

答案 2 :(得分:1)

我设法通过使用最近像素插值的外边界来修复它,并为此设置alpha = 0.

它工作得很好,但由于我需要存储alpha映射,因此它的原始内存消耗是原来的两倍。

final