使用带 three.js 的纹理图集时立方体边缘的接缝

Seams on cube edges when using texture atlas with three.js

在 three.js 中使用纹理图集时,立方体的水平面之间有接缝。
这是演示:http://jsfiddle.net/rnix/gtxcj3qh/7/ or http://jsfiddle.net/gtxcj3qh/8/(来自评论)

问题截图:
这里我使用repeat和offset:

    var materials = [];
    var t = [];
    var imgData = document.getElementById("texture_atlas").src;
    for ( var i = 0; i < 6; i ++ ) {
      t[i] = THREE.ImageUtils.loadTexture( imgData ); //2048x256
      t[i].repeat.x  = 1 / 8;
      t[i].offset.x = i / 8;
      //t[i].magFilter = THREE.NearestFilter;
      t[i].minFilter = THREE.NearestFilter;
      t[i].generateMipmaps = false;
      materials.push( new THREE.MeshBasicMaterial( { map: t[i], overdraw: 0.5 } ) );
    }

    var skyBox = new THREE.Mesh( new THREE.CubeGeometry( 1024, 1024, 1024), new THREE.MeshFaceMaterial(materials) );
    skyBox.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, -1 ) );
    scene.add( skyBox );

图集的大小为 2048x256(2 的幂)。我也尝试过手动 UV 映射而不是重复,但结果是一样的。我使用 8 个图块而不是 6 个图块,因为我认为 1/6 的除法精度会导致问题,但事实并非如此。

这条线上的像素来自地图集中的下一个图块。我尝试了完全白色的图集,没有任何人工制品。这就解释了为什么 Z 面的垂直边界上没有接缝。我玩过过滤器、wrapT、wrapS 和 mipmap,但没有用。增加分辨率没有帮助。有8192x1024的图集http://s.getid.org/jsfiddle/atlas.png我试了另一个图集,结果一样

我知道我可以将图集拆分成单独的文件,而且效果很好,但不方便。

怎么了?

我认为问题是纹理 sheets 的过滤问题。在纹理 sheet 中的图像边界上,由于精度有限,GPU 可能会从正确图像或相邻图像中选择纹素。因为颜色通常非常不同,所以会导致可见的接缝。在常规纹理中,这是通过 CLAMP_TO_EDGE.

解决的

如果必须使用纹理别名,则需要通过填充图像边框来伪造 CLAMP_TO_EDGE 行为。请参阅此答案 https://gamedev.stackexchange.com/questions/61796/sprite-sheet-textures-picking-up-edges-of-adjacent-texture。它应该看起来像这样:(为清楚起见夸大了边框)

否则,更简单的解决方案是为每个面使用不同的纹理。 Webgl 支持立方体纹理,大多数情况下通常使用它来实现天空盒。

破解 uv,将所有值 1.0 替换为 0.999,将所有值 0 替换为 0.001 将虚假地解决部分问题。