OpenGL-立方体上的白色边缘


12

在我制作的类似于《我的世界》的游戏中,我的立方体上出现白色边缘:

在此处输入图片说明

在深色纹理中更明显。正在按以下方式设置纹理: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

有什么帮助吗?


3
您能否显示一些有关如何渲染每个多维数据集以及如何放置多维数据集的代码?
joncodo 2012年

1
包裹纹理有什么不同吗?您要绑定的纹理外观/大小是什么?
Chuck D

我只是想指出,我已经看到这也发生在使用小瓷砖的大型纹理地图集中。例如,假设您有一个1024 * 1024的图块集/地图集,而您使用的是32 * 32的图块。您会舍入错误,因为映射到所述图块的小数点很小。这使得精度几乎不可能。一个办法?将图集地图细分为单个图块。这是Minecraft曾经或曾经做过的。他们有一个很大的图块,在运行时将它们切成单独的纹理。
Krythic

Answers:


19

这类问题有两种可能的原因,具体取决于它是哪种问题。我将同时列出:

1.您正在沿着砖的边缘从纹理中看到其他颜色。

在我看来,这是这种情况下的问题,因为所有边缘像素都是纹理中可能出现的三种颜色之一:白色,黑色和棕色。

如果您正在单个纹理(纹理图集)中紧挨着使用多个平铺图像,就像我想的那样,这是不可避免的。发生这种情况是因为GPU不能将三角形边缘的插值与纹理的插值完美匹配,并且相邻纹理很少。

您可以做很多事情。

  • 使用数组纹理而不是纹理图集。阵列纹理由一堆相同大小的2D图像组成,您可以指定第三个坐标来选择一个。它完全可以替代纹理图集,而不会出现过滤问题。但是,阵列纹理是一项较新的功能,在您使用的OpenGL版本中可能不可用。
  • 在每个纹理图块中生成一个1像素的边框,该边框将复制相邻常规像素的颜色。(这实际上是在重新实现GL的功能CLAMP[_TO_EDGE],但是以一种了解纹理地图集的方式进行-由于大多数瓷砖边缘不在纹理边缘,因此使用它没有效果。)这是我在本篇文章中使用的解决方案在类型上,立方体。除了使用更多的纹理内存外,我没有其他的缺点。
  • 稍微插入纹理坐标,以使它们不会一直到达纹理图块的边缘。与中间的像素相比,过多执行此操作将导致纹理边缘明显变薄。
  • 每个图块类型使用单个纹理。这增加了纹理切换成本。

2.您将看到瓷砖之间的缝隙。

在这种情况下,我认为这不是问题所在,因为没有空白可以看到,但是为了完整起见,我将其包括在内。

当您没有为相邻图块的相交边缘的顶点提供完全相同的坐标时,可能会发生这种情况,这通常是由于浮点误差引起的。举例来说,如果你有大小为0.6瓦,并在计算瓷砖的右边缘x=100(100*0.6) + 0.6和瓷砖的左侧边缘x=101(100*0.6),你不会得到完全相同的答案,其差异可作为小斑点可见差距。

解决方案是确保算法是一致的;一些方法可以这样做:

  • 确保您不是(甚至是间接地)进行计算index*size + size,而不仅仅是(index+1)*size
  • 确保您的算术是正确的;最简单的方法是将图块大小精确地设置为1.0,即使使用32位浮点数(无论如何,距原点最多1600万个块)进行计算,也将导致精确的整数算术运算。
  • 使用实际整数进行顶点坐标计算;这使您拥有更大的范围。

对我来说似乎是缝隙-考虑到微小而锋利的位,没有纹理渗出(除非有相当高的分辨率纹理)。
马里奥(Mario)

谢谢,稍微插入纹理坐标似乎可以解决此问题。
路易斯·克鲁兹

@Mario我认为这是NEAREST放大倍数-注意瓷砖内部的尖锐边框。因此,从这个角度来看,它是无限分辨率的纹理。
凯文·里德

您也可以使用纹理数组来避免切换成本。
danijar
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.