本文介绍了更改 Three.js collada 对象的纹理和颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从官方网站获得了使用 ColladaLoader.js 处理我的 collada 对象 (.dae) 的three.js 示例.现在我的问题是,如何更改加载的 collada 对象颜色属性并添加自定义纹理?我尝试添加纹理但没有运气.

I recently got three.js example from the official site working with my collada objects (.dae) using the ColladaLoader.js.Now my question is, how do i change the loaded collada object color attribute and add a custom texture?? I tried adding the texture with no luck yet.

这是我的代码(与原始示例略有不同):

Here is my code (slightly changed from the original example):

function load_model(el) {

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container, stats;

            var camera, scene, renderer, objects;
            var particleLight, pointLight;
            var dae, skin;

            var loader = new THREE.ColladaLoader();
            loader.options.convertUpAxis = true;
            loader.load( '/site_media/models/model.dae', function ( collada ) {
                dae = collada.scene;
                skin = collada.skins[ 0 ];

                dae.scale.x = dae.scale.y = dae.scale.z = 0.90;
                dae.updateMatrix();

                init(el);
                animate();

            } );

            function init(el) {

                container = document.createElement( 'div' );
                el.append( container );

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.set( 2, 2, 3 );

                scene = new THREE.Scene();


                scene.add( dae );

                particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
                scene.add( particleLight );

                // Lights

                scene.add( new THREE.AmbientLight( 0xcccccc ) );

                var directionalLight = new THREE.DirectionalLight(/*Math.random() * 0xffffff*/0xeeeeee );
                directionalLight.position.x = Math.random() - 0.5;
                directionalLight.position.y = Math.random() - 0.5;
                directionalLight.position.z = Math.random() - 0.5;
                directionalLight.position.normalize();
                scene.add( directionalLight );

                // pointLight = new THREE.PointLight( 0xffffff, 4 );
                // pointLight.position = particleLight.position;
                // scene.add( pointLight );

                renderer = new THREE.WebGLRenderer();
                renderer.setSize( window.innerWidth/2, window.innerHeight/2 );


                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                //

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth/2, window.innerHeight/2 );

            }

            //

            var t = 0;
            var clock = new THREE.Clock();

            function animate() {

                var delta = clock.getDelta();

                requestAnimationFrame( animate );

                if ( t > 1 ) t = 0;

                if ( skin ) {

                    // guess this can be done smarter...

                    // (Indeed, there are way more frames than needed and interpolation is not used at all
                    //  could be something like - one morph per each skinning pose keyframe, or even less,
                    //  animation could be resampled, morphing interpolation handles sparse keyframes quite well.
                    //  Simple animation cycles like this look ok with 10-15 frames instead of 100 ;)

                    for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {

                        skin.morphTargetInfluences[ i ] = 0;

                    }

                    skin.morphTargetInfluences[ Math.floor( t * 30 ) ] = 1;

                    t += delta;

                }

                render();
                stats.update();

            }

            function render() {

                var timer = Date.now() * 0.0005;

                camera.position.x = Math.cos( timer ) * 10;
                camera.position.y = 2;
                camera.position.z = Math.sin( timer ) * 10;

                camera.lookAt( scene.position );

                particleLight.position.x = Math.sin( timer * 4 ) * 3009;
                particleLight.position.y = Math.cos( timer * 5 ) * 4000;
                particleLight.position.z = Math.cos( timer * 4 ) * 3009;

                renderer.render( scene, camera );

            }


}

推荐答案

在遇到很多问题之后,我们在 ColladaLoader.js 中编写了一个小 hack,采用了@gaitat 的想法女巫基本上替换了图像中纹理的旧路径,在数组中传递一些新路径,并使用正则表达式来解析图像标记下的 .png 或 .jpg 的 xml.不确定是否有更简单的方法,但由于支持有限,我们不得不以某种方式提出解决方案

After many problems, we wrote a small hack in ColladaLoader.js taking the idea from @gaitatwitch basically replaces the old path to the textures from the images, passing some new ones in an array, and using regular expressions to parse the xml for the .png or .jpg under images tag. Not sure if there is an easier way but since support was limited we had to come up with a fix somehow

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( "//dae:library_images/dae:image", _Image, "image" );

    for(var i in imageReplace) {
        var iR = imageReplace[i];

        for(var i in images) {
            var image = images[i];

            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( "//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;

};

这篇关于更改 Three.js collada 对象的纹理和颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 04:31