【问题标题】:Seams on cube edges when using texture atlas with three.js使用带有three.js的纹理图集时立方体边缘上的接缝
【发布时间】:2016-05-08 21:40:10
【问题描述】:

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

问题截图:
这里我使用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我又试了一个图集,结果还是一样。

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

怎么了?

【问题讨论】:

  • 不是答案,但稍微改进了你的小提琴:jsfiddle.net/gtxcj3qh/8
  • 我扩展了您的小提琴并通过使用画布作为位图源而不是图像 (jsfiddle.net/gtxcj3qh/14) 使其工作。原始图像在单独的画布上逐块绘制,然后用于创建单独的纹理。我在这里问了一个非常相似的问题 (stackoverflow.com/questions/43401684/…) .. 但我没有使用你的方法,而是创建了一个自定义 UV 贴图和一个单一的纹理......但是结果和你的一样。

标签: three.js texture-mapping uv-mapping texture-atlas


【解决方案1】:

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

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

否则,更简单的解决方案是为每个面使用不同的纹理。 Webgl 支持立方体纹理,通常大部分时间用于实现天空盒。

【讨论】:

  • “夸张的边框”不是完美的解决方案。可能根本没有完美的解决方案。
  • 我同意夸张的边缘不是一个好的解决方案,但是这个想法给了我一个灵感来找到这个问题的解决方案。解决方案是将瓷砖排列成与瓷砖相邻的方式它们将在 3D 对象中相邻。这样他们的边缘就会接触到他们将在 3D 对象中接触的边缘。可以在此处找到有关此解决方案的更详细说明:stackoverflow.com/questions/43401684/…(这是部分重复的问题/答案,因为使用了不同的应用纹理方法)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-23
    • 2017-01-18
    • 2012-11-19
    • 2012-11-24
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多