要实现的效果如图所示:
左侧是插入的3D人物,类似AI智能助手的角色。
我们这里是通过React做的。需要用到以下工具或者网站:
readyplayer.me/ 自定义3D人物
Blender 3维设计软件,3D文件格式转化,主要是fbx和glb的互转
www.mixamo.com/ 人物动画绑定
react + three + @react-three/fiber + @react-three/drei 用于web渲染3D
以下是实现步骤:
设计3D人物
打开readyplayer,可以上传图片或者选择自定义用来定义一个3D人物,这个过程跟很多游戏中的捏脸功能是差不多的。设计好之后导出这个模型,导出的格式是glb的,如果不需要模型动画,这个时候就可以直接将模型引入到react项目中。
模型文件格式转化
通过将模型导入到blender中,把glb格式的文件导出为fbx,导出时需要勾选保留贴图材质信息,模式选择复制。
注意:在导出前,需要将贴图进行解压到当前文件夹中,不然在把导出的fbx模型上传到mixamo网站时,显示的会是白模。
动画绑定
上传模型,选择动画,导出。 导出的文件是fbx格式,需要再次通过blender转化为glb格式。
页面渲染
安装3D渲染组件
npm install @react-three/fiber three @react-three/drei
3d模型方式项目文件夹中,比如src/assets/assistant.glb
导出模型文件
util.js
import assistantModel from '../assets/assistant.glb' export const agentModel = assistantModel
5. 页面渲染
model.tsx
import {Canvas, extend, useFrame} from '@react-three/fiber'; import {OrbitControls, useAnimations, useGLTF} from '@react-three/drei'; import { agentModel } from '../../utils' function Model({ url }) { const { scene, animations } = useGLTF(url); // 加载 glTF 模型 const { actions, mixer } = useAnimations(animations, scene); // 提取动画 useEffect(() => { if (actions) { actions['Armature|mixamo.com|Layer0'].play(); // 播放指定动画 } }, [actions]); useFrame((state, delta) => { mixer.update(delta); // 更新动画 }); return <primitive object={scene} position={[0, -1, 0]}/>; } import { PlaneGeometry } from 'three'; import {useEffect} from "react"; // 注意: PlaneGeometry 代替 PlaneBufferGeometry // 扩展 three.js extend({ PlaneGeometry }); export default function AgentModel() { return ( <Canvas camera={{ position: [0, 2, 5], fov: 30 }} shadows> <OrbitControls /> <ambientLight intensity={0.5} /> <directionalLight position={[5, 5, 5]} /> <Model url={agentModel}/> </Canvas> ); }