【问题标题】:Three.js - changing collada texture works, but not with canvasThree.js - 改变 collada 纹理有效,但不适用于画布
【发布时间】:2014-02-04 11:58:17
【问题描述】:

我正在研究 Three.js 并尝试使用 vrml,现在使用 collada 文件。

导入 collada 文件有效。它可以与 webGL 和画布一起使用作为后备:我的 3D 模型旋转,显示模型……在 webGL 中,我什至可以拥有阴影、凹凸等美妙的效果。

我确实实现了加载另一个纹理文件,将其分配给 webGL 渲染器……但在这种特殊情况下,画布渲染器完全失败:帧从 60fps 下降到 2fps,并且纹理在多边形上“滑动”。

我想我为了将纹理“修复”到模型而错过了一些东西,或者在导入纹理时我可能错过了一些参数?在不改变纹理的情况下再次正常工作......但我真的需要这样做:p

这是一个工作预览: http://dokmixer.com/three-tests/

这是魔法失败的部分:

//model loading
      loader = new THREE.ColladaLoader();
      loader.load('models/collada/7cm.005.dae',function colladaReady( collada ){
        player = collada.scene;
        skin = collada.skins [ 0 ];
        player.scale.x = player.scale.y = player.scale.z = 0.10;

        if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
          var newskinTexture = new THREE.ImageUtils.loadTexture( 'models/collada/dokMixer.png' );
          themodel = collada.scene.children[0];
          themodel.material = new THREE.MeshBasicMaterial( { map: newskinTexture, overdraw: true} );
        }
        else {
          var newskinTexture = new THREE.ImageUtils.loadTexture( 'models/collada/dokMixer.png' );
          var bumpTexture = new THREE.ImageUtils.loadTexture( 'models/collada/noise.png' );
          bumpTexture.anisotropy = 2;
          player_material = collada.scene.children[0].material;
          themodel = collada.scene.children[0];
          themodel.material = new THREE.MeshPhongMaterial( { map: newskinTexture, bumpMap: bumpTexture, bumpScale: 0.05} );
        }

        //utile pour avoir les ombres
        daemesh = player.children[0];
        daemesh.castShadow = true;
        daemesh.receiveShadow = true;

        scene.add( player ); 
      });

要研究的部分是第一个 if 语句(因为我正在使用 Safari 测试画布,然后扩展到其他支持画布的设备)。分配新材质时,渲染器完全失败。您可以通过Safari进入页面来测试效果。

注意:如果有任何相关信息,我正在使用 OSX。

任何帮助表示赞赏:)

编辑:我想我在这里设置了一个新材料,而不是只替换源图像文件?

【问题讨论】:

    标签: canvas three.js textures collada uv-mapping


    【解决方案1】:

    好的,终于找到解决方法了!

    我为画布交换纹理的方式是错误的,我认为这是一个错误。 我在psychok7 找到了关于这个答案的线索。

    好吧,我没有加载然后更改纹理……我更改了 ColladaLoader.js 文件中的代码。嗯,几乎一样。由于我使用“加载”,我在加载函数中添加了几次 imageReload,并且在调用“解析”函数时。然后,在解析函数中,我也做了一些更改,因为给出的代码在他们的链接上是错误的。 对于那些感兴趣的人,一份更改列表和我的最终代码。遗憾的是,我无法实现“相同”的功能(发送一组纹理,执行 regExp 的操作,并一次替换多个纹理),这部分对我来说是错误的,因为我只需要更改一个纹理文件......

    • 我不做 iamge.init_from = iR.new_image;在 regExp 循环的东西中……而是添加 image.init_from = iR;就在正则表达式之前。
    • 在我的文件中调用函数时,我发送了一个数组……它没有记录,没有示例,并且很难理解它。好吧,不要尝试直接发送 .png 或 .jpeg url,将这些名称放在一个表中,然后放在调用该数组的函数中。不要忘记删除路径,因为它应该与您的 collada 文件中描述的路径相同(所以在我的例子中,只是纹理名称,因为我的 collada 文件与纹理共享相同的文件夹)。
    • 在psychok的代码中,“parseLib”调用中显然存在错误,他在其中编写了类似parseLib(“//dae:library_materials/dae:material”, Material, “material”);而不是 parseLib("library_materials material", Material, "material"); (这是有效的,并且是原始代码)。

    所以,长话短说,这是我调用 collada 的代码

     loader = new THREE.ColladaLoader();
          newtextures = ['dokMixer.png'];
          loader.load('models/collada/7cm.005.dae', newtextures,function colladaReady( collada ){
            player = collada.scene;
            skin = collada.skins [ 0 ];
            player.scale.x = player.scale.y = player.scale.z = 0.10;
    
            //i'll add code here later for extra bump mapping on webgl versions
    
            //usefull for shadows on webgl version
            daemesh = player.children[0];
            daemesh.castShadow = true;
            daemesh.receiveShadow = true;
    
            scene.add( player ); 
          });
    

    这是 colladaLoader 中的代码。它是函数加载和解析的替代品。

    function load ( url, imageReplace, readyCallback, progressCallback ) {
    
        var length = 0;
    
        if ( document.implementation && document.implementation.createDocument ) {
    
            var request = new XMLHttpRequest();
    
            request.onreadystatechange = function() {
    
                if( request.readyState == 4 ) {
    
                    if( request.status == 0 || request.status == 200 ) {
    
    
                        if ( request.responseXML ) {
    
                            readyCallbackFunc = readyCallback;
                            parse( request.responseXML, imageReplace, undefined, url );
    
                        } else if ( request.responseText ) {
    
                            readyCallbackFunc = readyCallback;
                            var xmlParser = new DOMParser();
                            var responseXML = xmlParser.parseFromString( request.responseText, "application/xml" );
                            parse( responseXML, imageReplace, undefined, url );
    
                        } else {
    
                            console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" );
    
                        }
    
                    }
    
                } else if ( request.readyState == 3 ) {
    
                    if ( progressCallback ) {
    
                        if ( length == 0 ) {
    
                            length = request.getResponseHeader( "Content-Length" );
    
                        }
    
                        progressCallback( { total: length, loaded: request.responseText.length } );
    
                    }
    
                }
    
            }
    
            request.open( "GET", url, true );
            request.send( null );
    
        } else {
    
            alert( "Don't know how to parse XML!" );
    
        }
    
    }
    
    function parse( doc, imageReplace, callBack, url ) {
    
        COLLADA = doc;
        callBack = callBack || readyCallbackFunc;
    
        if ( url !== undefined ) {
    
            var parts = url.split( '/' );
            parts.pop();
            baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
    
        }
    
        parseAsset();
        setUpConversion();
        images = parseLib( "library_images image", _Image, "image" );
    
        for(var i in imageReplace) {
            var iR = imageReplace[i];
    
            for(var i in images) {
                var image = images[i];
                //added line, but no multiple textures !
                image.init_from = iR; 
    
                //RegExp and patt.test not working
                var patt=new RegExp('[a-zA-Z0-9\-\_]*\/'+iR.name,'g');
                //if(image.id==iR.id)
                //
                if(patt.test(image.init_from))
                    image.init_from = iR.new_image; 
            }//for
        }
    
    
        materials = parseLib( "library_materials material", Material, "material" );
        effects = parseLib( "library_effects effect", Effect, "effect" );
        geometries = parseLib( "library_geometries geometry", Geometry, "geometry" );
        cameras = parseLib( "library_cameras camera", Camera, "camera" );
        lights = parseLib( "library_lights light", Light, "light" );
        controllers = parseLib( "library_controllers controller", Controller, "controller" );
        animations = parseLib( "library_animations animation", Animation, "animation" );
        visualScenes = parseLib( "library_visual_scenes visual_scene", VisualScene, "visual_scene" );
        // materials = parseLib( "//dae:library_materials/dae:material", Material, "material" );
        // effects = parseLib( "//dae:library_effects/dae:effect", Effect, "effect" );
        // geometries = parseLib( "//dae:library_geometries/dae:geometry", Geometry, "geometry" );
        // cameras = parseLib( ".//dae:library_cameras/dae:camera", Camera, "camera" );
        // controllers = parseLib( "//dae:library_controllers/dae:controller", Controller, "controller" );
        // animations = parseLib( "//dae:library_animations/dae:animation", Animation, "animation" );
        // visualScenes = parseLib( ".//dae:library_visual_scenes/dae:visual_scene", VisualScene, "visual_scene" );
    
        morphs = [];
        skins = [];
    
        daeScene = parseScene();
        scene = new THREE.Object3D();
    
        for ( var i = 0; i < daeScene.nodes.length; i ++ ) {
    
            scene.add( createSceneGraph( daeScene.nodes[ i ] ) );
    
        }
    
    // unit conversion
    scene.position.multiplyScalar(colladaUnit);
    scene.scale.multiplyScalar(colladaUnit);
    
        createAnimations();
    
        var result = {
    
            scene: scene,
            morphs: morphs,
            skins: skins,
            animations: animData,
            dae: {
                images: images,
                materials: materials,
                cameras: cameras,
                effects: effects,
                geometries: geometries,
                controllers: controllers,
                animations: animations,
                visualScenes: visualScenes,
                scene: daeScene
            }
    
        };
    
        if ( callBack ) {
    
            callBack( result );
    
        }
    
        return result;
    
    }
    

    希望这对某人有所帮助!玩得开心 ! :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-08
      • 2020-05-30
      • 2011-06-13
      • 2013-11-28
      • 2012-01-17
      • 1970-01-01
      • 2012-10-06
      • 2013-11-14
      相关资源
      最近更新 更多