【问题标题】:Assigning materials to an OBJLoader model in three.js在 three.js 中将材质分配给 OBJLoader 模型
【发布时间】:2013-04-18 11:33:46
【问题描述】:

我已经使用以下代码导入了一个 OBJ 模型:

var loader = new THREE.OBJLoader();
loader.addEventListener('load', function (geometry) {
    object = geometry.content;
    scene.add(object);
});
loader.load('ship.obj');

它工作正常,但每当我尝试向其添加材质时,它要么没有效果,要么模型消失。我以为我可以这样做:

var ship = new THREE.Mesh(object, material);

但这不起作用。有谁知道这样做的方法,或者是否有可能?我也尝试过使用 OBJMTLLoader,但它只会增加复杂性,同时仍然不允许我更改材料。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    编辑:这个答案现在已经过时了。相反,请参阅@mightypile 的答案。


    假设你已经正确定义了material,试试这个:

    loader.addEventListener( 'load', function ( event ) {
    
        var object = event.content;
    
        object.traverse( function ( child ) {
    
            if ( child instanceof THREE.Mesh ) {
    
                child.material = material;
    
            }
    
        } );
    
        scene.add( object );
    
    });
    

    【讨论】:

    • 我们如何在加载例程之外影响模型?每当我尝试从我的渲染函数中更改它时,它都是未定义的,即使我将“对象”分配给全局变量(即“myMesh”)。
    • @Jackalope 之后您可以根据需要修改变量“material”,对象将相应更改。
    • @IsilmëO。加载器异步工作,主代码不等待加载器。如果您想在加载后立即更新对象,您将得到“null”异常。
    【解决方案2】:

    使用@WestLangley 的答案,我不断收到错误

    loader.addEventListener is not a function
    

    我的页面无法加载。根据discourse.threejs.org 的 Atul_Mourya 的说法,加载时在回调内部实现函数是一个更好的(或更最新的?)想法。我将他的建议与documentation 和@WestLangley 的helpful function 结合起来回答了同样的问题:

    var ship_material = new THREE.MeshBasicMaterial( { color: 0x444444 } );
    var loader = new THREE.OBJLoader();
    loader.load( 'ship.obj',
        function( obj ){
            obj.traverse( function( child ) {
                if ( child instanceof THREE.Mesh ) {
                    child.material = ship_material;
                }
            } );
            scene.add( obj );
        },
        function( xhr ){
            console.log( (xhr.loaded / xhr.total * 100) + "% loaded")
        },
        function( err ){
            console.error( "Error loading 'ship.obj'")
        }
    );
    

    这个例子还实现了进度和错误的回调,它对我有用。

    【讨论】:

      【解决方案3】:

      我使用 SketchUp 来制作我的模型。当我从 SketchUp 导出为 OBJ 文件格式时,生成的 zip 包含一个 MTL 文件;

      此代码将同时加载MTL 文件和OBJ 文件;当你scene.add(object)加载成功后,纹理会自动渲染(无需分配给child.material.map

      const loader = new OBJLoader(manager);
      
      const materialsLoader = new MTLLoader(manager);
      
      materialsLoader.load('models/obj/sketchup_export/d2e8bc61-6dd1-4554-b874-13b5364d656e.mtl', function (materialsCreator) {
      
          // https://threejs.org/docs/#examples/en/loaders/OBJLoader.setMaterials
          loader.setMaterials(materialsCreator);
      
      
          loader.load('models/obj/sketchup_export/d2e8bc61-6dd1-4554-b874-13b5364d656e.obj', function (obj) {
      
              object = obj;
      
          }, onProgress, onError);
      
      }, onProgress, onError);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-22
        • 2019-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        • 1970-01-01
        相关资源
        最近更新 更多