You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将带Shape Keys的Blender GLB模型导入ThreeJS/react-three-fiber?

带有多个Shape Keys的Blender GLB模型导入react-three-fiber时触发TypeError错误

错误信息

TypeError: Cannot read properties of undefined (reading 'length')

问题说明

当Blender模型仅含'Basis'形状键或无形状键时,能正常在react-three-fiber(r3f)中加载;但添加第二个形状键后导出GLB再导入就会触发上述错误。需要解决Blender导出前的正确设置,或r3f侧的处理方法,也接受实现Mesh形状动画的替代方案。

复现步骤

  • 在Blender中新建带立方体网格的文件
  • 给立方体添加两个形状键
  • 将模型导出为GLB格式
  • 执行npx gltfjsx cube.glb生成React组件
  • 引入组件后触发报错

自动生成的组件代码

import React, { useRef } from "react";
import { useGLTF } from "@react-three/drei";

export const Cube = (props) => {
  const { nodes, materials } = useGLTF("/cube.glb");
  return (
    <group {...props} dispose={null}>
      <mesh geometry={nodes.Cube.geometry} material={nodes.Cube.material} />
    </group>
  );
};

useGLTF.preload("/cube.glb");

解决方案

Blender导出设置修正

  1. 导出GLB时,务必勾选Mesh分类下的"Shape Keys"选项,确保形状键数据被正确导出
  2. 导出前对立方体应用所有变换:选中立方体后按Ctrl+A,依次应用位置、旋转、缩放,避免几何数据存在异常变换
  3. 检查形状键类型:新增的形状键需保持默认的"Relative"类型,不要修改为其他可能不兼容的类型

react-three-fiber侧处理

自动生成的组件未处理多形状键的morph数据,可手动修改组件来修复:

import React, { useRef, useEffect } from "react";
import { useGLTF } from "@react-three/drei";

export const Cube = (props) => {
  const meshRef = useRef(null);
  const { nodes } = useGLTF("/cube.glb");

  useEffect(() => {
    const geometry = meshRef.current?.geometry;
    if (!geometry) return;
    
    // 确保morphTargets数组存在,避免读取length时出错
    if (!geometry.morphTargets) {
      geometry.morphTargets = [];
      // 从morphAttributes转换为morphTargets(适配Three.js的期望格式)
      if (geometry.morphAttributes.position) {
        geometry.morphAttributes.position.forEach((attr, idx) => {
          geometry.morphTargets.push({
            name: `shapeKey${idx}`,
            vertices: attr.array
          });
        });
      }
      // 更新几何体以生效
      geometry.needsUpdate = true;
    }
  }, []);

  return (
    <group {...props} dispose={null}>
      <mesh ref={meshRef} geometry={nodes.Cube.geometry} material={nodes.Cube.material} />
    </group>
  );
};

useGLTF.preload("/cube.glb");

替代方案(形状动画实现)

如果上述方案仍有问题,可直接在r3f中实现形状动画:

  • 使用drei的MorphControls组件,直接绑定形状键的权重值来控制动画
  • 简单动画可通过useFrame钩子手动修改顶点数据,或使用Three.js的MorphTargetAnimation来管理

内容的提问来源于stack exchange,提问作者Jake Pitman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:43:38