C++ 在OpenGL中使用GL_线性纹理时的外部瑕疵
我成功地在openGL中使用纹理生成了高度贴图。下图显示了该数据的全貌。然而,当我在glTexParameteri(MinMag)中使用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)
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。请在边缘上贴一张最终结果的图片稍微模糊一点。但我可以接受。