我正在使用一个纹理图集,它是通过将 2 个相同大小的图像并排缝合在一起制成的。 当我修改纹理坐标时,我按以下顺序执行以下操作:
-
if(texCoordx>1) texCoordx = texCoordx % 1
- 所以一种纹理不会泄漏到另一种纹理中。 -
if(texCoordx<0) texCoordx = 1 + texCoordx
- 同样,一个纹理不会泄漏到另一个纹理中。 - 将纹理坐标缩放 0.5。
- 如果想在右侧绘制纹理,请添加 0.5。
这基本上很好,但是,我似乎在纹理 s 坐标接近 1 和 0 的边缘处“弄脏”。看起来它沿着 s 被弄脏了。 t 轴。我已附上屏幕截图。
我知道找到了一个答案 here但它只是稍微缩小了污迹。我正在使用自己的着色器,但它没有对纹理坐标进行任何修改。我还启用了GL_REPEAT
。有人知道任何可能的原因/解决方案吗?
最佳答案
如果我正确地解释了你的图片,这个纹理是来自图集的两个纹理(假设左边)之一,你原来的 texCoords 是(从左到右)类似的东西
0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2
在步骤 1 中进行自己的包装后,您现在会得到类似的内容
0.2, 0.4, 0.6, 0.8, 1, 0.2, 0.4, 0.6, 0.8, 1
,后来成为
0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.2, 0.3, 0.4, 0.5
这里我们看到了 0.5、0.1 处的问题,其中单调性发生了变化。 OpenGL 不知道您想要在左右方向上从 0.5 变为 0.1。它只需要差值,即 -0.4,因此从右到左插值回到纹理的开头(因此向后挤压这个小间隔内的整个纹理,因此沿着 t 轴它实际上是正确的)。这是因为 OpenGL 不知道您的纹理在纹理的中间包裹,因为它在概念上只看到一个大纹理,而不是小纹理的图集和 GL_REPEAT
包裹模式仅适用于大纹理的边缘。
在访问纹理之前,您必须在片段着色器中进行包装(前两个步骤)。所以你的纹理坐标都是单调的并且可以正确插值。然后在片段处您可以安全地包装纹理坐标。实际上,您可以在片段着色器中执行所有步骤。只需给它一个统一的图集内的偏移量(选择实际的子纹理)。然后,在访问纹理之前进行环绕、缩放并添加偏移量。
关于OpenGL - 纹理图集 "smudging",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6945655/