☰
3 步搞定 Blockbench 骨骼权重绘制:从 VertexGroups 到 Skinning
2026/9/26 2:43:37 网站建设 项目流程

3 步搞定 Blockbench 骨骼权重绘制:从 VertexGroups 到 Skinning

【免费下载链接】blockbenchBlockbench - A low poly 3D model editor项目地址: https://gitcode.com/GitHub_Trending/bl/blockbench

你刚在 Blockbench 里给低模角色绑完骨骼,一按播放——肩膀直接撕成两半。十有八九这不是建模的问题,而是骨骼权重没画好:顶点没拿到对应骨骼的权重,动画一来就被两边扯开。这篇以权重笔刷为主线,带你走一遍从 VertexGroups 创建到 Skinning 预览的完整路径,外加 3 个最常见的权重事故。5 分钟上手。

⚡ 为什么你的模型"动不起来":一次骨骼绑定翻车现场

场景很典型:一个方块人的模型绑了 Armature,手臂骨骼也摆好了位置,播放动画的那一刻,上臂和躯干之间的网格像被手撕的纸一样裂开,甚至整块飞出屏幕。

根因其实就一句话:顶点不知道听谁的。Skinned Mesh 的变形逻辑是"每个顶点被若干骨骼按各自权重拉扯",如果你从没给顶点写过权重,所有骨骼对它的权重都是 0——骨骼转了,顶点原地不动,缝隙就这么撕出来了。

VertexGroups(顶点组)就是那张"听谁的话、听几成"的声明表。在 Blockbench 里它不单独存在,而是直接挂在每根骨骼上。

VertexGroups 到底在管什么:3 个数字完成一次骨骼绑定

整个数据结构可以压缩成三要素:一个顶点、一根骨骼、一个权重值。顶点可以同时对多根骨骼持有权重,理想情况下总和为 1。

具体存储长这样(骨架来自 js/outliner/types/armature_bone.ts):

this.vertex_weights = {}; // 形如 { "a1b2c3:17": 1, "a1b2c3:18": 0.6 } getVertexWeight(mesh, vkey) { const key = mesh.uuid.slice(0, 6) + ':' + vkey; return this.vertex_weights[key] ?? 0; } setVertexWeight(mesh, vkey, weight) { const key = mesh.uuid.slice(0, 6) + ':' + vkey; weight ? this.vertex_weights[key] = weight : delete this.vertex_weights[key]; }

也就是说,权重表的 key 是"网格 ID 前 6 位 + 顶点编号",value 就是 0~1 的浮点数。传 0 或不传等价于删除这条权重,所以"清掉权重"和"写权重"走的是同一个入口。

权重值含义
0.0这根骨骼对该顶点完全无效,等于没绑
0.5和邻接骨骼五五分成,顶点停在两者中间
1.0顶点完全跟随这根骨骼,动画里它只认这一个方向

权重相关的动作注册都汇聚在 js/modeling/mesh_editing.js,里面 import 了 set_vertex_weights 这套"选中顶点 → 选骨骼 → 填权重"的对话框逻辑。

🖌️ 动手:框选 → 权重笔刷 → 镜像,笔刷权重绘制全流程

先说结论:80% 的权重靠笔刷磨出来,框选只负责铺底。下面按顺序做。

框选顶点,让权重"扩散"出去

  1. 编辑模式下把选择切到顶点层级,拉框框住上臂全部顶点(漏掉的用 Shift 点选补上)。
  2. 在 Outliner 里选中对应骨骼,Shift+E可以给当前骨骼快速加子骨——先保证骨骼链和模型对得上。
  3. 触发"设置顶点权重"动作,选上臂骨骼,权重填1.0,勾选 overwrite,把这块区域彻底划归它。
  4. 没把握哪块归谁时,直接点"计算顶点权重"让引擎自动分配一遍,再手动修正——它的算法在 js/modeling/mesh/attach_armature.ts,按"顶点离骨骼线段多近、是否被骨骼轮廓环包围"来打分。
  5. 留一手:关节处(肘、肩、胯)的顶点先别给满权重,给到 0.5 左右,留给笔刷过渡。

拿权重笔刷把过渡区域"磨"平滑

  1. 在 Outliner 选中目标骨骼(比如前臂骨),在 Toolbox 点权重笔刷,核心逻辑在 js/modeling/weight_paint.ts。
  2. 底部两个滑杆:size(默认 50)管笔刷直径,limit(默认 100)是"画上去想达到的权重值"。
  3. 按住鼠标在肘部区域拖动,圈内顶点按距离衰减混合向 limit 靠近。衰减核心不长:
const falloff = (1 - distance / radius) * (1 + baseRadius); const influence = Math.hermiteBlend(Math.clamp(falloff, 0, 1)); if (event.ctrlKey) { value = value * (1 - influence); // Ctrl:减去 } else { value = value + (limit - value) * influence; // 默认:向目标值混合 } value < 0.04 ? deleteWeight(vkey) : setWeight(value); // 自动清掉微量权重

注意最后一行:小于 0.04 的权重会被直接删掉,所以"擦掉"一笔就够干净,不用抠像素。

  1. 按住 Ctrl 切减去模式,把画歪的地方扣回来;按住 Shift 强度降为 1/8,专门给过渡带做细磨。
  2. 混合模式选 "set" 时,给这根骨加权重会自动从其他骨等量扣减——总权重天然不超过 1。

这套屏幕坐标 → 模型空间的映射,和 UV 编辑里 js/texturing/uv.js 的 getBrushCoordinates 是同款思路:先算笔刷半径覆盖范围,再对覆盖到的顶点逐一点算。这些按钮背后的动作注册系统,入口在 js/interface/actions.js 和共享动作表里。

镜像复制,省掉一半工作量

  1. 确认左右网格关于 X=0 对称摆放——镜像识别靠"找到对面的镜像顶点",摆歪了它找不到对应点,直接不生效。
  2. 打开 Mirror Modeling 开关,并在工具配置里勾上 enabled(两处都要开)。
  3. 只画左侧:brush 每落一笔,js/modeling/mirror_modeling.ts 里的 symmetrizeArmature 会把刚改的顶点权重同步写到右侧镜像骨骼上。
  4. 中间轴上的顶点(x≈0)会被跳过,不会自我覆盖——脊柱附近的权重建议单独手画。
  5. 画完切到"顶点权重"显示模式扫一眼左右对称性,色块不对称的地方就是漏网的。

🦴 Skinning 技术:骨骼矩阵怎么搬动顶点

权重画完,变形公式只有一条:最终位置 = Σ(骨骼世界矩阵 × 逆绑定矩阵 × 静息位置)× 该骨权重。

function applyBoneInfluence(vertex, boneList) { const rest = vertex.position.clone().applyMatrix4(vertex.inverseBind); const result = new THREE.Vector3(); for (const {bone, weight} of boneList) { if (weight <= 0) continue; result.add(rest.clone() .applyMatrix4(bone.matrixWorld) .multiplyScalar(weight)); } return result; }

一句话人话:顶点先"还原"到绑定时刻的姿势,再让每根骨骼按自己动画后的姿态把它拉过去,各拉各的比例由权重决定。骨骼的世界矩阵和逆绑定矩阵的更新逻辑在 js/modeling/transform.js 这条变换链上。

两条性能建议,够用就行:

  • 权重烘焙:把权重表烘成顶点数据随几何体一起导出(glTF 的 JOINTS/WEIGHTS 属性),运行时零查表开销。
  • 顶点合并:相邻顶点权重差小于 0.01 的,合并成共享顶点,既省顶点数又天然消除接缝——笔刷那行< 0.04 删权重就是同一思想的轻量版。

🕳️ 踩坑记录:权重衰减 Falloff 最常见的 3 起事故

坑 1:权重总和溢出,手臂像面团一样膨胀

事故现象:播放动画时某块区域被"吹大",越动越肿。原因:用 "add" 混合模式在同一批顶点上连刷了多根骨骼,权重和远超 1。修复:

  1. 混合模式切回 "set",加权重时自动从其他骨扣减。
  2. limit 滑杆压到 60~80 重刷一遍事故区域。
  3. 切到顶点权重显示模式复核——一个顶点被两根骨骼同时亮满就是还没修干净。

坑 2:关节处动画抖动,肘部像"腿软"

事故现象:弯曲手臂时过渡区高频颤动。原因:两根骨骼影响区的边界太陡,骨骼转 1° 顶点位移差就很大,帧与帧之间互相抢。修复:

  1. 范围滑杆调大(比如 8 → 12),重刷过渡区把过渡带拉宽。
  2. falloff 换成 hermite spline,让衰减曲线变圆润。
  3. 抖动顽固时跑一次"计算顶点权重"重算,再手动微调回退的部分。

坑 3:过渡区出现一条"硬边"

事故现象:关节弯下去的瞬间,皮肤表面折出一道清晰的折线。原因:用 constant falloff(硬衰减)画的,权重从 1 直接跳到 0,中间没有过渡顶点。这个坑我上周也踩过,重刷一次就好。修复:

  1. falloff 改回 linear 或 hermite,limit 降到 50 左右。
  2. 按住 Shift(1/8 强度)沿折线补刷一两遍,把硬切磨成渐变。
  3. 折线所在的环如果本来就是分裂顶点,在建模菜单里把它们焊接合并,避免变形时各自为政。

🎯 收尾:从 VertexGroups 到 Skinning 技术

到这里你手里已经有一条完整链路:框选铺底权重的 VertexGroups,笔刷把 Falloff 过渡磨平滑,镜像把工作量砍半,Skinning 公式负责把骨骼矩阵和权重合成最终动画。剩下的功夫都花在"看"上——多切顶点权重显示模式,眼睛比任何算法都先发现问题。

下一步建议:读一遍 js/modeling/mesh/attach_armature.ts 里自动权重的打分逻辑,你会发现它处理"顶点被骨骼环包围"的几何判断比想象中讲究,改一改就能变成自己的自动绑骨脚本。源码可以本地拉下来翻:git clone https://gitcode.com/GitHub_Trending/bl/blockbench

【免费下载链接】blockbenchBlockbench - A low poly 3D model editor项目地址: https://gitcode.com/GitHub_Trending/bl/blockbench

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询