brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
blender-mcp用 Blender MCP(blender-mcp 插件 + socket)程序化驱动 Blender 做 3D 动画管线的实战方法论 + evaluator + 踩坑。 当任务涉及:用 Blender 给角色做/改动画、重定向 Mixamo 动作、IK 摆姿势、NLA 合成多 clip、导出 glTF/GLB、 在 Blender 里渲染验证、清理/重绑骨、把 Tripo/FBX 模型加工成带多动作的 AR 模型 —— 时使用本 skill。 出现 blender、blender-mcp、execute_code、bpy、armature、retarget、IK、glTF导出、骨骼动画、动画评估 等关键词也应触发。 配套:动画来源/管线的全局地图见 `ar-3d-animation-pipeline`;Tr…
Independent GitHub snapshot · Automated classification · Original documentation governs
ar-3d-animation-pipeline;Tripo 建模绑骨见 tripo-api。
⚠️ 活文档:每次实践有新经验就往"踩坑/经验"追加。我(agent)通过 MCP 给运行中的 Blender 发 Python,程序化地导入/绑骨/K帧/重定向/渲染/导出 —— 不靠人手 K,也不依赖 Mixamo 在线。比纯 JS 程序化烘焙强:有 IK、约束、曲线缓动、NLA 合成、以及"渲染回环"自己边做边看。
brew install --cask blender(Blender 5.x)。bpy.ops.preferences.addon_install(filepath="addon.py"); bpy.ops.preferences.addon_enable(module="blender_mcp_addon"); bpy.ops.wm.save_userpref()(插件 raw 在 raw.githubusercontent.com/ahujasid/blender-mcp/main/addon.py)。claude mcp add blender -- uvx blender-mcp + codex mcp add blender -- uvx blender-mcp(两边连同一个 Blender)。N 键 → 侧边栏 BlenderMCP 标签 → Connect to Claude(监听 localhost:9876)。GUI 那步代替不了。mcp__blender__* 工具要重启会话才出现(MCP 中途加的);在那之前直接走 socket(见下)。插件在 localhost:9876 收裸 JSON:{"type":..., "params":{...}} → {"status":"success"|"error", "result"|"message":...}。
get_scene_info / execute_code(不是 execute_blender_code!)/ get_viewport_screenshot / get_object_info / 各资产站(polyhaven/hyper3d/sketchfab/hunyuan3d)。scripts/blender_cmd.py:python blender_cmd.py scene|exec <pyfile>|shot <out.png>。get_scene_info 看现状。bpy.ops.import_scene.fbx(filepath=...)(扩展名最好真是 .fbx)。bpy.ops.export_scene.gltf(filepath, export_format='GLB', use_selection=True, export_skins=True, export_animations=True, export_yup=True)。mixamorig:Head 的冒号在 glTF 导出里保留;three.js GLTFLoader 加载时会把 :→去掉/净化,重定向/clip 命名要对齐。arm=bpy.data.objects['Armature']; bpy.context.view_layer.objects.active=arm
bpy.ops.object.mode_set(mode='POSE')
pb=arm.pose.bones['mixamorig:RightArm']; pb.rotation_mode='XYZ'
sc=bpy.context.scene
for f,(rx,ry,rz) in keyframes:
sc.frame_set(f); pb.rotation_euler=(rad(rx),rad(ry),rad(rz)); pb.keyframe_insert('rotation_euler')
缓动:fc.keyframe_points[i].interpolation='BEZIER'/'EASE';或整条 F-curve 加 modifier。预备/缓动/重叠要主动设,否则机械。
bpy.ops.nla.bake(frame_start,frame_end, only_selected=True, visual_keying=True, clear_constraints=True, bake_types={'POSE'}),再导出。export_animation_mode='ACTIONS' 让每个 Action 成一个 glTF animation(Greet/Idle/Talk/Pour…)。对动画逐帧 scene.frame_set(f) + depsgraph 更新,读 evaluated mesh 顶点 / 骨 head-tail 世界坐标,算:
mathutils.bvhtree.BVHTree.FromObject + bvh.overlap(bvh) → 手插身体、臂穿帽、脚穿地。AnimationMixer 播 → 确认:骨名解析对、不 T-pose/不炸、循环顺、iOS 能播、移动端性能。Blender 里好看 ≠ 引擎里对(导出保真/插值/性能差异)。
Evaluator = 闭环:授权 → 几何门禁 → 渲染+打分 → 修 → 重复;最后引擎实测。mixamorig: 净化。核心约束:workflow 的 codex/claude agent 是文本 agent——能读文件/跑 shell,但看不到图;且单个 Blender 实例不能并行驱动(socket 抢占)。所以分工:
W1设计 → 我授权 → 几何evaluator → W2解读 → 我修 → 我渲染 → W3审(喂视觉) → 我导出 → 引擎实测。/tmp/x.png,它准确描述了连环图内容)→ 真·agent 视觉评审解锁:渲染连环图 → 把文件路径给 codex critic → 它真看图评。不用我转述!get_viewport_screenshot 在 workflow worker 里被 "user cancelled"(权限/审批),且单 Blender 多 agent 并行会抢 → 不要让 critic 自己截图;由我(主循环)渲染到文件,codex critic 读文件。multi-critic-review 的视觉 lens 应走 codex + 传图片路径。Tripo 模型无 Jaw/blendshape,但若嘴是"张嘴笑"建模(有口腔内部),可手加一根下巴骨做振幅级口型(实测可行):
mixamorig:Jaw(parent=Head)。⚠️ 支点(head)高度=头号坑:必须落在真实颌关节=嘴缝线/耳侧高度(rel-height≈0.62=移动区上沿那条),绝不能放脑门顶(我曾误放 z=0.724=脑门 → 张嘴时整下半脸绕高支点画大弧、向前甩 → 真机看是"整张脸歪/斜甩"而非下巴掀开)。tail 朝前下到下巴尖;roll=0(开合轴≈world-Y、左右对称)。移动 rest 骨不改静止网格,只改旋转支点/轴,可反复调。0.60~0.66 羽化、别渗进脸颊/法令区(渗了→张嘴带动整下脸=另一种"脸抖");被削权重转给 Head(守恒、跟头不动)。实战教训(真机):单根 Jaw 骨旋转,因为嘴是静态网格(唇不相对张合),看到的永远是"整下半脸往下沉",不是"嘴在说话"——再调参也到顶。用户一眼就看穿。真正的解 = blendshape/morph(让唇真的分开),业界(VRM A/I/U/E/O、Oculus viseme、ARKit、Rhubarb、met4citizen/TalkingHead three.js)无一例外。
mouthOpen 形态键——下唇缘下拉+上唇微抬(smoothstep 羽化),用同一振幅驱动 mesh.morphTargetInfluences[idx](three GLTFLoader 读 morphTargetDictionary['mouthOpen']);Jaw 骨降为微动(~5°)只做下巴辅助。导出 export_morph=True;优化必须 --simplify false(简化会毁形态键),并验 GLB extras.targetNames 有 mouthOpen。确定性 scrub:rest vs 张嘴(取最大角),算每顶点 world 位移,断言:
jaw_pivot_rel 应≈移动区上沿(嘴线,~0.62);若 pivot 远高于上沿 → 支点过高 → 大弧斜甩(我踩过:pivot 0.73 vs 上沿 0.66 → 真机"脸歪")。asym = |meandispL−meandispR|/max(...) 应 <5%(修好后实测 1.5%;歪时这条会爆)。做好(1-DOF 下巴):① 运行时 Web Audio AnalyserNode 取正在播放的同一段音频 RMS → Jaw(时序天然零漂移,别烘长口型轨);② 映射曲线 jaw=smoothstep((rms−floor)/(ceil−floor))×maxOpen + 噪声地板(静音闭嘴)+ 上限(别尖叫)+ 时间平滑(attack50ms/release120ms 防抖);③ 一个 audio 当唯一时钟——字幕按 currentTime、嘴按实时振幅、body Talk 独立循环,三者挂同一音频→不相对漂移。
完整 evaluator(口型对应,四层):
execute_code 才是跑 Python 的命令(execute_blender_code 报 Unknown command)。execute_javascript/页面内容报 "Chrome not running" = Chrome 的 "Allow JavaScript from Apple Events" 没开(这是 Control_Chrome,非 Blender,记此防混淆)。import_scene.fbx 前先确认/改 .fbx。action.fcurves(改分层 action / slot+channelbag)。设关键帧插值要走新 API:for layer in action.layers: for strip in layer.strips: cb=strip.channelbag(action_slot); cb.fcurves —— 写带 try/except 兜旧版。keyframe_insert 本身不变。(arm.matrix_world @ pose_bone.matrix).translation,算 根漂移/脚z漂移/手到脊柱轴距/二阶差分jerk/首末帧姿势角差(循环接缝);阈值用"占身高%"做尺度无关。脚本见项目 scripts/(bl 内联)。导出的 mixamo GLB 身高被归一到 ~1.0,相对阈值正好用。bpy.ops.nla.bake(visual_keying=True, clear_constraints=True, use_current_action=True) 烘成纯 FK 导出)一次解决 → 开放的举手挥手。够取类动作 IK >> 猜 euler,实锤。