在 Texture OpenGL 中使用 GL_LINEAR 时的外部伪像
Outer artifacts when using GL_LINEAR in Texture OpenGL
我成功地在 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时的图像(一切正常)
这是使用GL_Linear时的图像(外插伪像出来了)
那么,有人知道如何删除这个伪影吗?
注意:当color = 0时,外层黑色也被认为是数据。
我假设您的纹理包装当前为 GL_REPEAT。你应该试试另一个。
GL_MIRRORED_REPEAT 或 GL_CLAMP_TO_EDGE 应该可以。
错误是因为从 "null color" 插值到 colr table 中的实际颜色。简而言之:你不能那样做。这个概念被打破了。回到绘图板。
最简单的解决方案是不使用空颜色,将四边形限制在有效区域,并按照其他人的建议进行GL_CLAMP_TO_EDGE。
一个更棘手的方法是设置GL_NEAREST然后自己在着色器中编写线性采样,用tex
采样纹理加上一些偏移(曼哈顿距离应该没问题)并跳过空颜色混合时(跳过部分是您原始概念中缺少的部分)。棘手的部分是正确设置偏移量。
我通过使用最近像素的插值值制作外边界并为此设置 alpha = 0 来修复它。
它工作得很好,但是由于我还需要存储 alpha 贴图,它的内存消耗是原始内存消耗的 2 倍。
我成功地在 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时的图像(一切正常)
这是使用GL_Linear时的图像(外插伪像出来了)
那么,有人知道如何删除这个伪影吗?
注意:当color = 0时,外层黑色也被认为是数据。
我假设您的纹理包装当前为 GL_REPEAT。你应该试试另一个。
GL_MIRRORED_REPEAT 或 GL_CLAMP_TO_EDGE 应该可以。
错误是因为从 "null color" 插值到 colr table 中的实际颜色。简而言之:你不能那样做。这个概念被打破了。回到绘图板。
最简单的解决方案是不使用空颜色,将四边形限制在有效区域,并按照其他人的建议进行GL_CLAMP_TO_EDGE。
一个更棘手的方法是设置GL_NEAREST然后自己在着色器中编写线性采样,用tex
采样纹理加上一些偏移(曼哈顿距离应该没问题)并跳过空颜色混合时(跳过部分是您原始概念中缺少的部分)。棘手的部分是正确设置偏移量。
我通过使用最近像素的插值值制作外边界并为此设置 alpha = 0 来修复它。
它工作得很好,但是由于我还需要存储 alpha 贴图,它的内存消耗是原始内存消耗的 2 倍。