gltf material 覆盖停止动画混合器
gltf material override stops animation mixer
我对 gltf 模型的问题非常困惑。如果我尝试覆盖 gltf 的 material,动画将停止。我觉得是override的update函数和animation mixer的tick function不知何故发生了碰撞有关,但我一直没能自己解决。
我希望有人能指出发生这种情况的方向。
这是一个活生生的例子:http://motiondolphins.com/app_onlyFefo/index.html
非常感谢。这是代码本身。注释部分是 material 的覆盖。如果我取消注释,新的 material 加载但动画停止:
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);
}
})
重要的是要记住 three.js 中的 Material 实际上代表 WebGL shader program, not just the visual "look" of an object. MeshToonMaterial extends MeshPhongMaterial,并继承了几个与动画相关的属性,这些属性需要保留以便动画能够工作:
newMaterial.skinning = oldMaterial.skinning;
newMaterial.morphTargets = oldMaterial.morphTargets;
newMaterial.morphNormals = oldMaterial.morphNormals;
在这种情况下,我认为只有 .skinning
属性 很重要,因为该模型使用骨架。
我对 gltf 模型的问题非常困惑。如果我尝试覆盖 gltf 的 material,动画将停止。我觉得是override的update函数和animation mixer的tick function不知何故发生了碰撞有关,但我一直没能自己解决。
我希望有人能指出发生这种情况的方向。 这是一个活生生的例子:http://motiondolphins.com/app_onlyFefo/index.html
非常感谢。这是代码本身。注释部分是 material 的覆盖。如果我取消注释,新的 material 加载但动画停止:
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);
}
})
重要的是要记住 three.js 中的 Material 实际上代表 WebGL shader program, not just the visual "look" of an object. MeshToonMaterial extends MeshPhongMaterial,并继承了几个与动画相关的属性,这些属性需要保留以便动画能够工作:
newMaterial.skinning = oldMaterial.skinning;
newMaterial.morphTargets = oldMaterial.morphTargets;
newMaterial.morphNormals = oldMaterial.morphNormals;
在这种情况下,我认为只有 .skinning
属性 很重要,因为该模型使用骨架。