Vue3 + Three.js + GLB 实现 AI 工作台 3D 机器人助手组件

📅 2026/7/8 4:42:05
Vue3 + Three.js + GLB 实现 AI 工作台 3D 机器人助手组件
我把 AI 工作台的 3D 机器人入口抽成了一个 Vue3 组件Three.js GLB 实战技术栈Vue3、TypeScript、Vite、Three.js、GLB/glTF、ShaderMaterial适合场景AI 工作台、智能客服、数据分析后台、SaaS 控制台、企业管理系统首页很多 AI 项目功能已经能跑了但页面第一眼还是很普通一个输入框、一段欢迎语再放一个静态机器人图标。能用是能用但客户看演示时很难马上感受到“这是一个 AI 产品”。所以我把工作台首页里的 3D 机器人入口单独抽成了一个独立模块AI Orb 3D Assistant。它不是一张图片而是一个 Vue3 Three.js 的 3D 助手组件可以直接放进后台首页、AI 工作台或智能客服欢迎区。最终效果现在 Demo 页面很简单只保留核心区域AI 工作台欢迎区 ├── 3D 机器人助手 ├── 标题文案 └── 输入框没有复杂业务没有后端依赖。拿到源码后重点就是把这个 3D 机器人组件放进自己的页面。为什么要单独做成模块AI 工作台的入口形象很重要。用户打开页面后第一眼看到的是不是“智能助手入口”会直接影响产品观感。尤其是企业项目、演示 Demo、私活交付、毕业设计这类场景一个有质感的 3D 助手入口能比普通图标更快建立“AI 产品”的感觉。这个模块适合放在AI 工作台首页智能客服欢迎区数据分析助手首页管理后台 Dashboard企业知识库问答入口SaaS 控制台首屏它解决的不是算法问题而是页面第一印象和产品入口感。模块能力能力说明GLB 模型加载使用 Three.jsGLTFLoader加载二进制 3D 模型透明背景Canvas 背景透明可以自然融入页面正交相机适合头像、欢迎区、助手入口这类 UI 场景自动居中缩放根据模型包围盒自动适配容器原版流光边缘通过 ShaderMaterial 保留蓝、青、粉流光质感轻微待机动画模型会有很克制的左右摆动响应式容器使用ResizeObserver适配容器尺寸资源释放页面卸载时释放 renderer、geometry、material 和动画目标很简单像普通 Vue 组件一样使用一个 3D 机器人助手。文件结构独立项目结构如下ai-orb-3d-assistant ├── public │ └── static │ └── models │ └── ai-orb-assistant.glb ├── src │ ├── components │ │ └── AiOrbAssistant3D.vue │ ├── App.vue │ ├── main.ts │ └── style.css ├── package.json ├── vite.config.ts └── README.md真正接入项目时核心只需要两个东西AiOrbAssistant3D.vue ai-orb-assistant.glb安装依赖pnpmaddthreepnpmadd-Dtypes/three如果你使用 npmnpminstallthreenpminstall-Dtypes/three页面中如何使用script setup langts import AiOrbAssistant3D from /components/AiOrbAssistant3D.vue /script template section classworkspace-hero div classassistant-orb AiOrbAssistant3D / /div div classhero-copy h1AI 工作台 3D 助手组件/h1 p一个可以直接接入后台、智能客服、数据分析工作台的 3D 机器人入口模块。/p /div /section /template配套样式示例.workspace-hero{display:flex;align-items:center;justify-content:center;gap:30px;}.assistant-orb{width:88px;height:88px;flex:0 0 auto;border-radius:999px;}.hero-copy h1{margin:0 0 12px;font-size:36px;font-weight:820;line-height:1.16;}.hero-copy p{margin:0;color:#536176;font-size:16px;line-height:1.65;}这样页面上就能出现一个独立的 3D 机器人入口。核心实现拆解下面只讲关键思路完整源码可以放到资源包里交付。1. 创建透明 WebGL 渲染器后台页面里的 3D 组件不能自带黑底或白底所以渲染器需要开启透明背景constrenderernewTHREE.WebGLRenderer({alpha:true,antialias:true,powerPreference:high-performance,})renderer.outputColorSpaceTHREE.SRGBColorSpace renderer.toneMappingTHREE.NoToneMapping renderer.shadowMap.enabledfalse这个组件定位是 UI 入口不是全屏 3D 场景所以关闭阴影减少不必要的性能成本。2. 使用正交相机头像类 3D 组件更适合用正交相机。它不会产生夸张透视放在页面里更稳定constcameranewTHREE.OrthographicCamera(-viewSize/2,viewSize/2,viewSize/2,-viewSize/2,0.01,100,)camera.position.set(3.35,0.02,0)camera.lookAt(0,0,0)3. 自动缩放和居中不同 GLB 模型的原始尺寸不一样所以组件里通过包围盒自动计算缩放比例functionfitModelToView(root:THREE.Group,frame:THREE.Group){constboxnewTHREE.Box3().setFromObject(root)constsizebox.getSize(newTHREE.Vector3())constmaxAxisMath.max(size.x,size.y,size.z)||1frame.scale.setScalar(1.9/maxAxis)frame.updateMatrixWorld(true)constscaledBoxnewTHREE.Box3().setFromObject(frame)constcenterscaledBox.getCenter(newTHREE.Vector3())frame.position.sub(center)}这样后续想换模型也不用从零调scale和position。4. 播放模型自带动画如果 GLB 里带动画可以用AnimationMixer循环播放constmixernewTHREE.AnimationMixer(gltf.scene)for(constclipofgltf.animations){constactionmixer.clipAction(clip)action.setLoop(THREE.LoopRepeat,Number.POSITIVE_INFINITY)action.reset()action.play()}在渲染循环里更新mixer?.update(delta)5. 增加轻微待机摆动即使没有复杂表情也可以加一点非常克制的待机动作modelFrame.rotation.yMath.sin(elapsedTime*1.8)*0.16注意幅度不能大。工作台页面不是游戏界面动效应该有存在感但不能抢输入框和业务内容的注意力。6. Shader 流光边缘机器人边缘的蓝、青、粉渐变是视觉重点。这里使用ShaderMaterial做一个轻微流动效果uniform float uTime; varying vec3 vLocalPosition; void main() { float angle atan(vLocalPosition.z, vLocalPosition.y); float flow fract(angle / 6.28318530718 uTime * 0.075); vec3 blue vec3(0.10, 0.33, 1.00); vec3 cyan vec3(0.18, 0.95, 1.00); vec3 pink vec3(0.86, 0.45, 1.00); vec3 color mix(blue, cyan, smoothstep(0.00, 0.45, flow)); color mix(color, pink, smoothstep(0.56, 0.92, flow)); gl_FragColor vec4(color, 1.0); }每一帧更新uTimematerial.uniforms.uTime.valueelapsedTime这个小效果会让机器人看起来更像一个 AI 助手而不是静态贴图。7. 浅色背景描边白色机器人放在浅色后台页面上很容易和背景融合。所以组件给机身加了一个很轻的背面描边constoutlineMaterialnewTHREE.MeshBasicMaterial({color:0xcbd6e2,depthWrite:false,opacity:0.6,side:THREE.BackSide,transparent:true,})constoutlinenewTHREE.Mesh(mesh.geometry,outlineMaterial)outline.scale.setScalar(1.034)mesh.add(outline)它不是粗黑边只是为了让模型在白底页面里更清晰。8. 响应式适配用ResizeObserver监听容器尺寸变化constresizeObservernewResizeObserver(resizeRenderer)resizeObserver.observe(container)然后同步更新 canvas 和相机renderer.setSize(width,height,true)constaspectwidth/height camera.left(-viewSize*aspect)/2camera.right(viewSize*aspect)/2camera.topviewSize/2camera.bottom-viewSize/2camera.updateProjectionMatrix()这样组件放在 88px、96px、120px 等不同容器里都能适配。9. 页面卸载时释放资源Three.js 组件一定要处理销毁否则后台路由切换多了以后容易显存泄漏onBeforeUnmount((){window.cancelAnimationFrame(animationFrameId)resizeObserver?.disconnect()mixer?.stopAllAction()modelRoot?.traverse((child){constmeshchildasTHREE.Meshif(!mesh.isMesh)returnmesh.geometry?.dispose()constmaterialsArray.isArray(mesh.material)?mesh.material:[mesh.material]for(constmaterialofmaterials){material?.dispose()}})renderer?.dispose()renderer?.domElement.remove()})这一步很关键也是把 3D 小效果做成可复用组件时最容易被忽略的地方。源码包内容我把它整理成了一个独立源码包ai-orb-3d-assistant ├── public/static/models/ai-orb-assistant.glb ├── src/components/AiOrbAssistant3D.vue ├── src/App.vue ├── src/style.css ├── package.json ├── vite.config.ts └── README.md包含内容Vue3 TypeScript 组件源码Three.js GLB 加载逻辑3D 机器人模型资源工作台欢迎区 DemoVite 项目接入说明常见结构说明也就是说它定位是一个可直接接入前端项目的 3D AI 助手入口模块不是完整 AI 系统。适合使用场景这个模块比较适合正在做 AI 工作台的前端开发者想给后台首页增加 AI 入口形象的项目接私活时需要快速提升页面观感的人做毕业设计、课程设计、演示 Demo 的同学做企业数字化系统希望页面更有 AI 感的团队如果你只是想学习 Three.js也可以参考这篇文章的拆解自己实现。如果你想节省调试时间也可以直接使用整理好的完整源码包不用自己找 3D 模型不用从零写 Three.js 初始化不用调相机、灯光和材质不用处理 GLB 动画播放不用处理路由切换资源释放可以直接放进自己的 AI 工作台页面源码获取方式完整源码已经整理为独立项目包包含 Vue3 组件源码、GLB 模型资源、工作台欢迎区 Demo 和接入说明。需要源码或交流接入问题请看主页详情。也可以在 CSDN 私信留言我看到后会回复。