如何在Three.js中重复纹理而不拉伸

How do I repeat textures without stretching in Three.js?

本文关键字:纹理 Three js      更新时间:2023-09-26

无论我做什么,我的纹理似乎都会被拉伸/缩放到我应用它们的网格的大小。我已经阅读了很多关于这个问题的答案,似乎没有一个解决方案能解决我的问题,所以我发布了一个新的解决方案。只是一点信息,

  • 我的纹理都是64x64像素
  • 我正在预加载所有纹理
  • 我正在使用Web GL渲染器

这是我的代码

makeTestObject:function()
{
    var scope = this,
        tileGeometry = new THREE.BoxGeometry(TILE_SIZE , TILE_HEIGHT , TILE_SIZE),
        texture = new THREE.Texture(preloadedImageObject),
        textureMaterial = new THREE.MeshLambertMaterial({map:texture}),
        tile = new THREE.Mesh(tileGeometry , new THREE.MeshFaceMaterial(
        [
            textureMaterial, // +x
            textureMaterial, // -x
            textureMaterial, // +y
            textureMaterial, // -y
            textureMaterial, // +z
            textureMaterial // -z
        ]));
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    tile.position.y = BASE_HEIGHT * 2;
    tile.castShadow = true;
    tile.receiveShadow = true;
    texture.needsUpdate = true;
    scope.scene.add(tile);
}

如果我执行texture.repeat.set(x , x)并将x设置为任何类型的值,纹理似乎就会消失,我只剩下一个平坦的颜色。

知道我做错了什么吗?

好的,所以对于标准的长方体几何体(正方形或矩形),解决方案是这样的;

makeTestObject:function()
{
    var scope = this,
        tileGeometry = new THREE.BoxGeometry(TILE_SIZE , TILE_HEIGHT , TILE_SIZE),
        texture = new THREE.Texture(preloadedImageObject),
        textureMaterial = new THREE.MeshLambertMaterial({map:texture}),
        tile = new THREE.Mesh(tileGeometry , new THREE.MeshFaceMaterial(
        [
            textureMaterial, // +x
            textureMaterial, // -x
            textureMaterial, // +y
            textureMaterial, // -y
            textureMaterial, // +z
            textureMaterial // -z
        ]));
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    tile.geometry.computeBoundingBox();
    var max = tile.geometry.boundingBox.max;
    var min = tile.geometry.boundingBox.min;
    var height = max.y - min.y;
    var width = max.x - min.x;
    texture.repeat.set(width / TEXTURE_SIZE , height / TEXTURE_SIZE);
    texture.needsUpdate = true;
    scope.scene.add(tile);
}

关键是为纹理的重复正确设置比率。您可能还希望为每个面创建一个新材质,而不是反复引用同一材质对象。