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



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

这是我第一次做网页图形。我正在将一个 3D 模型查看器示例与三个可以加载 glTF 模型的.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 所示的纹理模式?

多亏了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

相关内容

  • 没有找到相关文章

最新更新