gltf 材质覆盖停止动画混合器

Posted

技术标签:

【中文标题】gltf 材质覆盖停止动画混合器【英文标题】:gltf material override stops animation mixer 【发布时间】:2018-07-16 10:15:02 【问题描述】:

我非常纠结于 gltf 模型的问题。如果我尝试覆盖 gltf 的材质,动画就会停止。我认为它与覆盖的更新功能和动画混合器的滴答功能以某种方式发生碰撞有关,但我还没有设法自己解决。

我希望有人能指出为什么会发生这种情况的方向。 这是一个活生生的例子:http://motiondolphins.com/app_onlyFefo/index.html

提前非常感谢。这是代码本身。注释部分是材料的覆盖。如果我取消注释,新材料会加载但动画会停止:

        AFRAME.registerComponent("fefo", 
            init: function() 

                var texture = new THREE.TextureLoader().load( 'models/static.png' );
                texture.wrapS = THREE.RepeatWrapping;
                texture.wrapT = THREE.RepeatWrapping;
                texture.repeat.set( 20, 20 );


                this.material  = new THREE.MeshToonMaterial(
                    bumpMap:texture,
                    bumpScale:0.03,

                    color : 0xffffff
            );

            this.el.addEventListener('model-loaded', () => this.update());


            var el = this.el;
            setTimeout(()=>
                var model = el.getObject3D('mesh')       
                this.mixer = new THREE.AnimationMixer(model);
                var clips = model.animations || (model.geometry || ).animations || 
                [];
                console.log(this.mixer)
                console.log(el)
                console.log(clips[0])
                const action = this.mixer.clipAction(clips[0], model);
                action.setDuration(10).setLoop(THREE.LoopRepeat).play();
                console.log(action)
            , 3000)
            ,

            /////////////////HERE I TRY TO OVERRIDE THE MATERIAL, BUT IF I DO, ANIMATION STOPS

            update: function () 

            //      object = this.el.getObject3D('mesh');

            //     if (!object) return;
            //     object.traverse((node) => 

            //     if (node.isMesh) node.material = this.material;
            // ); 

        ,
            tick: function (t, dt) 

                if (this.mixer && !isNaN(dt)) this.mixer.update(dt / 1000);

            
        )

【问题讨论】:

【参考方案1】:

重要的是要记住,three.js 中的 Material 实际上代表 WebGL shader program,而不仅仅是对象的视觉“外观”。 MeshToonMaterial 扩展了MeshPhongMaterial,并继承了几个与动画相关的属性,这些属性需要保留才能使动画正常工作:

newMaterial.skinning = oldMaterial.skinning;
newMaterial.morphTargets = oldMaterial.morphTargets;
newMaterial.morphNormals = oldMaterial.morphNormals;

在这种情况下,我认为只有 .skinning 属性很重要,因为模型使用骨架。

【讨论】:

非常感谢唐的信息丰富的回答。确实,只需添加 this.material.skinning = true;在更新功能中解决了这个问题

以上是关于gltf 材质覆盖停止动画混合器的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL纹理覆盖材质颜色

如何从 GLTF 模型动态覆盖纹理 - Three.js

markdown 角度 - 材质 - 如何覆盖材质按钮样式

如何覆盖主题覆盖中所选颜色的材质ui以进行反应

将材质应用于 gltf 对象时出现未定义错误

我的材质 UI 自定义类被材质 UI 的默认类覆盖