Three.js加载GLB模型骨骼动画在Chrome中无法播放问题求助
你遇到的动画无法播放的问题,是以下3处配置遗漏导致的:
- 没有在每帧渲染时调用
AnimationMixer.update()方法驱动动画更新,且AnimationMixer实例的作用域限制导致渲染循环无法访问该实例 - 替换模型材质时没有开启蒙皮配置
skinning: true,骨骼动画的网格依赖该属性才能正确响应骨骼变换 - 直接取
mesh.children[0]修改属性的逻辑容错性低,若GLB模型层级嵌套较深容易误操作非蒙皮网格节点
修正后的完整代码如下:
let file, scale, backgroundColor; // 全局存储时钟用于计算帧间隔 const clock = new THREE.Clock() window.onload = loader; function loader (){ file = "Fox.glb"; scale = 1; backgroundColor = 0x000000; init(); } function init(){ //RENDERER myCanvas = document.getElementById('myCanvas'); renderer = new THREE.WebGLRenderer({ canvas: myCanvas, antialias: true }); renderer.setClearColor(backgroundColor); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); //CAMERA camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 1000 ); //SCENE scene = new THREE.Scene(); let controls = new THREE.OrbitControls(camera, renderer.domElement); camera.position.set( 0, 20, 100 ); controls.update(); //LIGHTS let light = new THREE.AmbientLight(0xffffff, 0.5); scene.add(light); let light2 = new THREE.PointLight(0xffffff, 0.5); scene.add(light2); let loader = new THREE.GLTFLoader(); // 将mixer声明提升到init作用域,方便render函数访问 let mixer = null; let mesh; loader.load(file, handle_load); function handle_load(gltf) { mesh = gltf.scene; //ANIMATION mixer = new THREE.AnimationMixer( gltf.scene ); let action = mixer.clipAction( gltf.animations[ 0 ] ); action.play(); // 遍历所有子网格替换材质,开启skinning支持骨骼动画 mesh.traverse((child) => { if(child.isMesh) { child.material = new THREE.MeshLambertMaterial({ skinning: true }) } }) mesh.scale.set(1,1,1) scene.add( mesh ); mesh.position.z = -10; } render(); function render() { // 获取帧间隔时间,更新动画 const delta = clock.getDelta() if(mixer) mixer.update(delta) renderer.render(scene, camera); requestAnimationFrame(render); } }
内容的提问来源于stack exchange,提问作者JPLEMARABOU
相关产品推荐
相关产品推荐

