在THREE.JS和GLTF中运行时导入另一个纹理

3
我在Three.JS上还是新手,但我已经取得了一些进展,只需要一些帮助。我在场景中加载了一个GLTF对象,我想让用户通过选择样式(就像定制功能)在网站上加载不同的纹理到对象上。
以下是我的代码,目前没有输出并且出现了以下错误:
在Chrome中:
"TypeError: Cannot set property 'map' of undefined"
在Firefox中:
"TypeError: model.material is undefined"
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('../gtf/green/green.png');
texture.flipY = false;

var loader = new THREE.GLTFLoader();
loader.load( '../gtf/Box.gltf', function ( gltf ) {
    model = gltf.scene;
    scene.add( model );
});

model.material.map = texture;

任何帮助都将不胜感激。
2个回答

1

loader.load() 函数是异步运行的,因此在调用它之后你不会立即设置 model 变量。所以你需要的解决方案是将 model.material.map = texture; 移动到回调函数中,像这样:

loader.load( '../gtf/Box.gltf', function (gltf) {
    model = gltf.scene;
    texture.flipY = false; // for glTF models only
    model.material.map = texture; // <-- move here
    scene.add( model );
});

这将确保您拥有一个有效的model对象可供使用。

嗨,Hugo,谢谢你。我已经让它工作了,而且感觉很满意。我发布了一个新问题,下面是链接,如果你对那个问题有任何见解,那就太棒了。https://stackoverflow.com/questions/52068620/create-an-array-of-meshes-from-object-three-js-and-gltf - TheGoldenD0nut

0
你遇到的问题是你分配为model的场景包含比网格和材质信息更多的信息。你需要迭代场景对象model以找到网格,然后相应地更改材质。虽然你使用的初始数据格式不同,但你要寻找的答案可以在此前的帖子中找到:

Change texture of loaded .obj in three.js at runtime

编辑:
@HugoTeixeira是对的,纹理的分配需要移动到loader.load()的回调函数中(抱歉,我之前完全忽略了这一点),但实际的分配model.material.map = texture;是行不通的。你仍然需要像上面提到的那样迭代gltf.scene对象,以找到你想要分配纹理的网格。

谢谢@jlcox5,看起来很有道理,我已经让它工作了。你知道吗,是否可以将纹理应用于模型的某个部分?因此,GLTF来自Blender,我能否将纹理应用于一侧?还是应该使用.obj和.MTL文件并使用对象数组? - TheGoldenD0nut
嘿@TheGoldenD0nut,GLTF格式指定您可以在一个文件中拥有多个网格。您应该能够通过上述迭代找到要更改的特定网格,并单独分配新的纹理。话虽如此,您的模型组织方式将取决于在Blender中构建它时以及创建GLTF文件时使用的导出器。打开.gltf文件并查找JSON blob中的“网格”条目以获取想法很容易。对于大多数格式,都会存在这样的问题。 - jlcox5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接