Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在OpenGL中使用GL_线性纹理时的外部瑕疵_C++_Opengl_Texture Mapping - Fatal编程技术网

C++ 在OpenGL中使用GL_线性纹理时的外部瑕疵

C++ 在OpenGL中使用GL_线性纹理时的外部瑕疵,c++,opengl,texture-mapping,C++,Opengl,Texture Mapping,我成功地在openGL中使用纹理生成了高度贴图。下图显示了该数据的全貌。然而,当我在glTexParameteri(MinMag)中使用GL_线性选项时,它会给我外部工件 这是我的参数 if (interpolate) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

我成功地在openGL中使用纹理生成了高度贴图。下图显示了该数据的全貌。然而,当我在glTexParameteri(MinMag)中使用GL_线性选项时,它会给我外部工件

这是我的参数

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";
“可变矢量2 tex;\n”
“统一int colorSizeI;\n”
“统一vec4颜色表[512];\n”
“统一vec2 minmaxZ;\n”
“统一的vec3背景色;\n”
“均匀采样2D漫反射;\n”
“均匀浮动透明度;\n”
“void main(){\n”
float color=texture2D(漫反射,tex).r;\n
“浮点h=(颜色-minmaxZ[0])/(minmaxZ[1]-minmaxZ[0]);\n”
“float colorSizeF=float(colorSizeI);\n”
“int i=0;\n”
“浮动j=0.0f;\n”
“vec3基;\n”
“如果(颜色==0.0f){\n”
base=vec3(0.0f,0.0f,0.0f);}\n
“else if(color=minmaxZ[1]){\n”
“base=colorTable[colorSizeI-1].xyz;}\n”
“否则{\n”
“而(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(基础,透明度);\n
“}\n”;
这是使用GL_时的图像(一切正常)

这是使用GL_Linear时的图像(外部插值伪影出现)

那么,有人知道如何移除这些工件吗


NB:当颜色为0时,外部黑色也考虑数据。

< P>我假设你的纹理包装目前是GLR-重复。你应该试试另一个


GL_镜像_重复或GL_夹紧_到_边应该可以工作。

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

最简单的解决方案是不使用空颜色,将四边形限制为仅有效区域,并按照其他建议执行GL_钳制到边


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

我通过使用最近像素的插值值创建外部边界,并将alpha=0来修复它

它工作得很好,但是它花费了原始内存消耗的2倍,因为我还需要存储alpha映射


夹紧边缘
GL_夹紧到_边缘
GL_夹紧
我使用了GL_夹紧到_边缘,我忘了提到,当z=0时,正方形外部的黑色实际上也是数据;所以我不相信这是因为texturewrap。你必须提供所有的
::glTexParameteri
调用,这样我们才能看到你在做什么如果你做
gl\u FragColor=texture2D(漫反射,tex)
我使用纹理来避免使用顶点和索引(减少内存)。在纹理(红色)中,数据包含将基于碎片着色器中的计算以颜色显示的高度贴图。因此,如果我做
gl_FragColor=texture2D(漫反射,tex)
它将不会显示我想要显示的数据。我使用了gl_CLAMP_to_EDGE,我忘了提到,当z=0时,正方形外部的黑色实际上也会显示数据;所以我不相信这是因为texturewrap。好吧,那么也许这一行就是问题所在:base=colorTable[colorSizeI-1].xyz;}看起来有问题,但无法为您提供更多帮助,因为我不知道统一值。我在
uniform vec4 colorTable[512]
中准备缓冲区,因为我的colorTable有一些选项,每个选项都有不同的颜色数。
colorSizeI-1
用于确保如果高度超过某个值,则颜色将是colorTable中的最后一个有效值。所以我试着像你建议的那样改变它,但是插值伪影仍然存在。我想现在我明白你想做什么了:你有一个高度值为0.0到1.0的纹理,但是这个纹理有一个边界值为1.0=最大高度。OpenGL现在将这些值沿1个边界沿中间插入。看起来您必须从纹理中删除边框或使用GL_。可以使用“transparent(alpha=0.0)”作为空颜色,然后预定义的混合函数应该可以再次工作。遗憾的是不能。它最多可以移除半个texelwidth的瑕疵,但空颜色仍会流入非空texel,例如,左上角texel的顶部将从红色变为黄色,而zufry希望它的边框变为蓝色。对于黑色区域,我将在那里设置alpha=0。我用黑色显示它,以便在这里更容易解释。还有黑色区域,它的高度=0,如果(颜色=0.0f){base=vec3(0.0f,0.0f,0.0f);},它进入这些
@安德烈亚斯:那么最终它是一个GL_线性的限制?你能提供你建议的方法的阅读材料吗?@zufryy这不是我以前知道的方法。如果您想阅读某些内容,请查看有关GL_LINEAR和GL_NEAREST的文档。确保您理解为什么会得到错误的图像输出,并尝试从中找出满足您需求的算法。祝你好运。@Andreas:问题是当使用GL_LINEAR时,当像素试图计算插值,而相邻像素中存在零点时,就会出现这种情况。因此,我只是将“虚拟”点作为外部边界,然后在那里应用alpha=0。请在边缘上贴一张最终结果的图片稍微模糊一点。但我可以接受。