如何使用threejs中的按钮更改Collada的颜色?

Posted

技术标签:

【中文标题】如何使用threejs中的按钮更改Collada的颜色?【英文标题】:How to change a color of Collada using a button in threejs? 【发布时间】:2019-06-10 16:51:04 【问题描述】:

我想创建一个带有交互式骨骼的骨架模型,这样如果您单击其中一个按钮,骨架的某些部分就会改变颜色。

我尝试在同一个位置添加两个相同的模型,但颜色不同,但这导致我的 collada 模型不在 y 轴上旋转。

<body>
    <script src="js/three.js"></script>                 
    <script src="js/loaders/ColladaLoader.js"></script> 
    <script src="js/Detector.js"></script>              

    <script>

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

        var container;
        var camera, scene, renderer, objects;           
        var dae;            
        var dae2;                   
        var loader = new THREE.ColladaLoader();

        loader.options.convertUpAxis = true;
        var url='obj/szkieletCube.dae';  

        loader.load( url, function ( collada ) 
            dae = collada.scene;
            dae.traverse( function ( child ) 
                if ( child instanceof THREE.SkinnedMesh ) 
                    var animation = new THREE.Animation( child, child.geometry.animation );
                    animation.play();
                
             );

            dae.scale.x = dae.scale.y = dae.scale.z = 100; 
            dae.rotation.y+=Math.PI/2;
            dae.position.y-=2048;
            dae.position.x-=0;
            dae.position.z+=0;
            dae.updateMatrix();

            dae.traverse( function ( child )   
                child.castShadow = true;
                child.receiveShadow = false;
             );            

            init();
            animate();
         );            

        function init() 
        

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 40000 );
            camera.position.set( Math.pow(2,13), 1024, 0);

            scene = new THREE.Scene();

            scene.add( dae );

            var light1  = new THREE.DirectionalLight( 0xffffff );
            light1.position.set(1, 1, 1);   
            scene.add( light1 );

            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight); 
            renderer.shadowMapEnabled=true;
            renderer.shadowMapType=THREE.PCFSoftShadowMap;

            container.appendChild( renderer.domElement );

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

        


        function onWindowResize()                  

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

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

        function animate()                 
            requestAnimationFrame( animate );
            render();
        
        var kat = 0;
        function render() 
            camera.position.y = 1024;
            kat -= -0.001;
            dae.rotation.y = Math.cos( kat ) * 10;
            camera.lookAt( scene.position );        
            renderer.render( scene, camera );
        

    </script>
</body>

【问题讨论】:

您的代码似乎基于一个非常旧的ColladaLoader 版本。使用以下示例作为与最新版本的 three.js (R100) 一起使用的入门模板:threejs.org/examples/webgl_loader_collada_skinning 【参考方案1】:

看,你在这里使用SkinnedMesh,它是Mesh的派生类 Mesh 本身有Mesh.material 属性。

所以你需要改变颜色的只是收集孩子,这样你就可以在按钮点击处理程序上单独访问它们。

这是你的代码调整:

    var daeChildren = ; // map dae child name => child node
    var loader = new THREE.ColladaLoader();

    loader.options.convertUpAxis = true;
    var url='obj/szkieletCube.dae';  

    loader.load( url, function ( collada ) 
        dae = collada.scene;

        ...

        dae.traverse( function ( child )   
            child.castShadow = true;
            child.receiveShadow = false;

            // 1. Collect DAE children here
            daeChildren[child.name] = child;
         );            

        ...

     );

然后单击按钮可以更改材质颜色:

function handleButtonClick() 
    // 2. drop texture if you need the mesh to be just colored
    daeChildren[child.name].material.map = null;

    // 3. set mesh color red
    daeChildren[child.name].material.color = new THREE.Color( 0xff0000 );

    // 4. tell threejs that material must be updated
    daeChildren[child.name].material.needsUpdate = true;

【讨论】:

以上是关于如何使用threejs中的按钮更改Collada的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

Threejs - 导入 collada 模型在 Chrome Android 上看起来很有趣,纹理未正确加载

Angle Threejs Collada

Threejs collada 3D模型在某些角度无法正确渲染

使用 pycollada 制作 3d 线条

更改 Three.js collada 对象的纹理和颜色

Threejs对象翻译和还原