边缘上的Skybox纹理伪像


12

我在Mac上绘制Skybox纹理时遇到奇怪的问题。在iPhone上,一切正常。我尝试更改近端和远端的值没有成功。

它是一个包含六个纹理的天空盒,对于每个纹理,我都设置为:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

可能是什么问题呢?

屏幕截图:

可见天空盒边缘的天空图像

编辑:

我尝试将背景色设置为红色,以确保其是否通过纹理渗出

我还尝试将纹理的坐标更改为:

float err_corr = 0.5 / TEXTURE_SIZE;

GLfloat vertices[24] = {    
        -1.0f - err_corr, -1.0f - err_corr,  1.0f + err_corr,
    1.0f + err_corr, -1.0f - err_corr,  1.0f + err_corr,
    -1.0f - err_corr,  1.0f + err_corr,  1.0f + err_corr,
    1.0f + err_corr,  1.0f + err_corr,  1.0f + err_corr,
    -1.0f - err_corr, -1.0f - err_corr, -1.0f - err_corr,
    1.0f + err_corr, -1.0f - err_corr, -1.0f - err_corr,
    -1.0f - err_corr,  1.0f + err_corr, -1.0f - err_corr,
    1.0f + err_corr,  1.0f + err_corr, -1.0f - err_corr,
    };

然后按以下顺序绘制框:
GLubyte indices[14] = {0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1};

解:

解决方案是为多维数据集本身设置GL_CLAMP_TO_EDGE

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Answers:


8

您确定要为每个纹理设置GL_CLAMP_TO_EDGE 吗?这是单个纹理状态的一部分,默认为GL_REPEAT,因此需要在与glBindTexture绑定之后完成。我意识到在原始文章中,您实际上是说您为每种纹理设置了纹理,但是我想知道代码实际上是什么样的?

例如:

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

glBindTexture(GL_TEXTURE_2D, tex1);
//upload texture, etc.

glBindTexture(GL_TEXTURE_2D, tex2);
//upload texture, etc.

这与以下内容不同:

glBindTexture(GL_TEXTURE_2D, tex1);
//upload texture, etc.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_2D, tex2);
//upload texture, etc.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

我发现了错误!不必为立方体贴图的每个纹理都设置GL_CLAMP_TO_EDGE,而是必须为cubemapp本身设置GL_CLAMP_TO_EDGE!glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
马丁·皮尔奇(Martin pilch)2011年

1

从纹理的左侧和右侧插入'0.5f / texture_width',从顶部和底部插入'0.5f / texture_height'。您会看到采样伪像-纹理采样器通常从纹理像素的中心采样,因此在左右,顶部和底部(0和1 uv),您将获得采样器超出范围时得到的所有纹理像素的50% 。那是纹理的另一面,或者是默认的采样颜色。


这就是为什么他得到了GL_CLAMP_TO_EDGE集合,它应该使边界样本取最近的纹理内像素的值。您所描述的内容可能效果很好,但是并不能解释为什么问题首先存在。
aaaaaaaaaaaaa

我已经尝试了一下,没有任何改变:/
马丁·皮尔奇(Martin pilch)2011年

0

我最好的猜测是MAC和iPhone之间的差异是由MAC上的抗锯齿引起的。我的3D编程有些生疏,但是我想您必须将所有正方形都设为同一网格的一部分或类似的东西。

肮脏的破解解决方案是将所有正方形都变得太大,以使它们重叠并相互裁剪,并相应地调整UV坐标。


我试图关闭抗锯齿(通过glDisable(GL_POLYGON_SMOOTH);)无效。我将天空框绘制为三角形带坐标为-1到1的三角形
马丁·皮尔奇(Martin Pitch)2011年

1
对我来说听起来不错。至少到目前为止,我还不确定,但是您可能希望通过发现黑色是背景渗漏还是纹理边缘显示为黑色来缩小问题的范围。如果您在人工制品后面的某个地方放置一个红色多边形,该人工制品会变成彩色吗?
aaaaaaaaaaaaa

我想尝试扩展墙壁,以便它们重叠(就像电子商务所写的一样)-我认为0.0001就足够了。您不必更改UV坐标。
zacharmarz 2011年

1/10000当然是不够的,问题的严重程度似乎在1/4到1/2像素范围内,因此,根据纹理大小,此功能起作用的最小幅度约为1/1000。鉴于纹理的性质,不调整UV坐标有点草率,可能不会引起明显的视觉跳动,但这仍然是错误的。无论如何,关于黑客的进一步建议应取决于我在先前评论中提出的问题的答案。
aaaaaaaaaaaa

伪影不是通过纹理渗出的背景。我将背景色设置为红色,没有任何变化。我也尝试过扩展纹理坐标
马丁·皮尔奇(Martin pilch)2011年

0

这是较旧的硬件(或iPhone)上的立方体贴图的常见问题。检查

GL_ARB_seamless_cube_map

扩展名(如果您的硬件可用)。如果是这样。通过使用它可以适当地解决问题。


问题出在GeForce 9400M而不是iPhone上。此扩展名不适用于我。
马丁·皮尔奇(Martin Pitch)2011年

无论是否无缝,这绝对不是由立方体贴图引起的问题。这是一个纹理包裹问题。
塔拉

0

是将这六个纹理设置为立方体贴图,还是将每个天空盒面分别用其自身的纹理渲染?我听说一些早期的 PC系统在处理立方体贴图时过滤效果很差,因为当在立方体边缘附近采样时,它们不一定从一个面纹理到下一个面纹理进行过滤。AFAIK SGX(iPhone GPU)应正确过滤边缘。

在我看来,你侧面纹理的底部看起来像是人造的蓝色。例如,您是否可以尝试将底行(或几行)像素设置为洋红色的丑陋阴影,看看是否会改变伪影的颜色?这可能会使您对可能发生或可能发生的事情有更多的了解。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.