使用Three.js以gltf格式更改纹理时,如何将纹理放置在正确的位置?

时间:2019-04-01 09:14:42

标签: javascript graphics three.js 3d gltf

我尝试通过将纹理替换为THREE.TextureLoader来动态更改glTF模型的纹理。纹理的颜色按照我的预期发生了变化,但是纹理的图案有些混杂。

这是我第一次制作网络图形。我正在将3d模型查看器示例与可以加载glTF模型的three.js重新混合。我想通过按钮动态更改纹理。我从各种格式中选择了glTF,因为它似乎是一个新标准。到目前为止,我能找到的最好的解决方案是在纹理加载器下面添加texture.flipY = false;,但是没有用。我还尝试更改了纹理对象中的某些值,但没有任何反应。

这是我加载模型的地方:

loader.load( urls, function (texture) {
    var pmremGenerator = new THREE.PMREMGenerator( texture );
    pmremGenerator.update( renderer );

    var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker(pmremGenerator.cubeLods);
    pmremCubeUVPacker.update( renderer );

    var envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
    var loader = new THREE.GLTFLoader().setPath( `models/${modelName}/`);

    loader.load(`${modelName}.gltf`, (gltf) => {

        gltf.scene.traverse((child) => {
            if (child.isMesh) {
                child.material.envMap = envMap;
            }
        });

        gltf.scene.scale.set(0.01,0.01,0.01)
        scene.add(gltf.scene);
    });

我尝试通过实现此功能来更改其纹理:

function changeColor(color) {

    const textureLoader = new THREE.TextureLoader();
    const texture = textureLoader.load(`models/${modelName}/textures/fabric-${color}.jpg`);

    texture.flipY = false;

    scene.traverse((child) => {
        if (child.isMesh) {
            if (child.material.map.format === 1022) {
                child.material.map = texture;
            }
        }
    });
}

尽管我可以瞄准想要的网格并更改其颜色,但纹理图案却很尴尬。它是用织物制成的椅子的顶部。

以文字形式绘制它,看起来像这样...

这应该是什么:

-------------------
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
-------------------
Figure 1

现实:

-------------------
|      +++++      |
|      +++++      |
| ++++++++++++++  |
| ++++++++++++++  |
| ++++++++++++++  |
|      +++++      |
|      +++++      |
-------------------
Figure 2

要明确: 通过上述功能更改纹理文件时,如何保留如图1所示的纹理图案?

1 个答案:

答案 0 :(得分:0)

由于DonMcCurdy的帮助,我终于得到了答案。

这确实是UV映射的问题。

要在正确的位置获得纹理,我需要添加以下内容:wrapS,wrapT和RepeatWrapping

function changeColor(color) {

    const textureLoader = new THREE.TextureLoader();
    const texture = textureLoader.load(`models/${modelName}/textures/fabric-${color}.jpg`);

    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    texture.flipY = false;

    scene.traverse((child) => {
        if (child.isMesh) {
            if (child.material.map.format === 1022) {
                child.material.map = texture;
            }
        }
    });
}

官方文档: https://threejs.org/docs/#api/en/textures/Texture