简体   繁体   English

three.js:将外部纹理应用到glTF

[英]three.js: Apply external texture to glTF

I have two files: "model.gltf" and "texture.jpeg".我有两个文件:“model.gltf”和“texture.jpeg”。 I want to apply texture file to model and render it using three.js but after 3 days of continuous research and hundreds of attempts, I just can't get it to work properly.我想将纹理文件应用到 model 并使用 three.js 进行渲染,但经过 3 天的持续研究和数百次尝试,我无法让它正常工作。 My method that sets the current object in the scene:我在场景中设置当前 object 的方法:

 /** * SET method: Sets object in the scene (deleting previous one) * * @author Anton Pernisch <anton@pernisch.dev> * @param {string} modelPath - Path to object in glTF format * @param {string} texturePath - Path to texture * @returns {boolean} * * @todo Texture */ SET_Object: function(modelPath, texturePath) { // Clear out the scene for (var i = this.prodconf3_scene.children.length - 1; i >= 0; i--) { obj = this.prodconf3_scene.children[i]; this.prodconf3_scene.remove(obj); } const modelLoader = new THREE.GLTFLoader(); modelLoader.load(modelPath, (gltf) => { // HERE? apply texture from texturePath to this gltf this.prodconf3_obj = gltf.scene; this.prodconf3_scene.add(this.prodconf3_obj); }); return true; }

This code imports glTF just fine, it's just black.这段代码很好地导入了 glTF,它只是黑色的。 Eventually, I was able to apply.jpeg texture to this model, but only sort of.最终,我能够将.jpeg 纹理应用到这个 model,但只是有点。 This is the best result I could get: here这是我能得到的最好结果:这里

And that was by this method:那是通过这种方法:

 /** * SET method: Sets current object to scene (deleting previous one) * * @author Anton Pernisch <anton@pernisch.dev> * @param {string} modelPath - Path to object in glTF format * @param {string} texturePath - Path to texture * @returns {boolean} * * @todo Texture */ SET_Object: function(modelPath, texturePath) { // Clear out the scene for (var i = this.prodconf3_scene.children.length - 1; i >=0; i--) { obj = this.prodconf3_scene.children[i]; this.prodconf3_scene.remove(obj); } const modelLoader = new THREE.GLTFLoader(); const textureLoader = new THREE.TextureLoader(); modelLoader.load(modelPath, (gltf) => { var model = gltf.scene; model.traverse((o) => { if (o.isMesh) { o.material = new THREE.MeshBasicMaterial({map: textureLoader.load(texturePath)}); } }); this.prodconf3_obj = model; this.prodconf3_scene.add(this.prodconf3_obj); }); return true; }

I have also tried creating texture by TextureLoader load method and then meshing it together with gltf.scene from modelLoader.load function.我还尝试通过 TextureLoader 加载方法创建纹理,然后将其与来自gltf.scene function 的modelLoader.load网格化。 That didn't work at all, I was getting那根本不起作用,我得到了

Uncaught TypeError: Cannot read property 'center' of undefined未捕获的类型错误:无法读取未定义的属性“中心”

error (I'm not sure about using gltf.scene as the first argument in THREE.Mesh() tho).错误(我不确定是否使用gltf.scene作为THREE.Mesh()中的第一个参数)。

So, my question is, what is the proper and updated approach to properly apply the texture to glTF in three.js?所以,我的问题是,将纹理正确应用于 three.js 中的 glTF 的正确和更新方法是什么?

This looks fine to me, but I wonder if we're supposed to pass a reference to an already loaded texture.这对我来说看起来不错,但我想知道我们是否应该传递对已加载纹理的引用。

Object3D#Traverse isn't asynchronous, so we'll have to update the material synchronously. Object3D#Traverse不是异步的,因此我们必须同步更新材质。

Live example . 活生生的例子

SET_Object: async function(modelPath, texturePath) {
    // Clear out the scene
    for (let i = this.prodconf3_scene.children.length - 1; i >= 0; i--) { 
        obj = this.prodconf3_scene.children[i];
        this.prodconf3_scene.remove(obj); 
    }

    const modelLoader = new THREE.GLTFLoader();
    const textureLoader = new THREE.TextureLoader();

    // Load texture
    const texture = await textureLoader.loadAsync(texturePath);
    texture.flipY = false;

    // Load model
    const { scene: model } = await modelLoader.loadAsync(modelPath);

    // Update model
    model.traverse((o) => {
        if (o.isMesh) {
            o.material.map = texture;
            o.material.needsUpdate = true;
        }
    });

    this.prodconf3_obj = model;
    this.prodconf3_scene.add(this.prodconf3_obj);
    
    return this.prodconf3_obj;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM