给博客人物加动作:一次转头效果的试错

从脸颊贴图碎片追到骨骼叠加,把人物响应收回到合适的幅度。

个人博客Three.js动画

这个博客的人物原本是一张盘坐托腮的画。给它加动作时,我希望读者点击旁边的物品,人物能稍微回应一下,再回到原来的姿态。

最初看起来只是一个很小的交互:左边的入口让头朝左,右边的入口让头朝右。真正放到页面里,右侧响应却显得不自然,脸颊还出现了碎片。

这次调整最后落在了三个地方:先弄清模型能支持什么,再检查最终叠加的旋转,最后把响应收回到一个足够小的范围。

先看画面出了什么问题

旧版响应中,左脸颊会暴露一块不连续的贴图。它不是简单的“动作太快”,减慢速度也不能改变被暴露出来的表面。

旧版人物动作截图,左脸颊靠近嘴角的位置出现不连续的贴图碎片。旧版响应
受限动作修复后的历史截图,人物保持小幅回应,脸颊没有出现前一张中的贴图碎片。修复后响应
左图是旧版响应,右图是缩小旋转并补偿父骨骼后的姿态。

需要先回到这个人物的制作方式。页面里的模型有网格和骨骼,但面部细节来自原画的正面投射。网格能转动,不代表眼镜、脸侧和五官已经拥有完整的侧面材质。

当转角增加,原先正面看不到或不明显的问题就暴露出来。这个时候,继续提高动作幅度,会让缺口更显眼。

一张正面画,能支持多大的转头

可以把正面投射理解成从一个固定方向,把画面映射到物体上。从原来的观察方向看,它能保持角色的样子;换一个角度,表面和画面的对应关系就可能不再合适。

正面画面从固定方向映射到人物表面;网格转动后侧面被暴露,原画没有提供完整侧面细节。
网格能够转动,正面画面却没有提供完整的侧面细节。

这也解释了另一个现象:人物默认看向左上,而点击右侧入口时,并没有自然地看过去。原画中的视线并不是独立眼球动画,转动头骨不能直接重画瞳孔和眼镜中的细节。

我把这一阶段的目标收小了:让人物做轻微回应。默认视线继续保留,大幅转头和完整右侧注视留给后续模型处理。

限制头部角度,还要算上身体

贴图问题之外,实际转角也比预想的大。旧版响应把鼠标偏移、头部运动和身体运动一起叠加,记录中的头部总转角接近 5°。

这里的“总转角”很重要。头骨是身体骨骼的子节点,身体转动时,头也会跟着走。只查看头骨自己的局部旋转,会遗漏父节点的影响。

身体骨骼是头骨的父节点。旧做法的身体转动与头部局部转动会组合;修复时检查最终头部姿态,并补偿父节点增量。
局部角度小,不等于渲染出来的最终角度也小。三维旋转按变换组合,不能简单相加。

修复中取消了鼠标自由移动带来的额外偏移,固定前后俯仰,再补偿身体骨骼的旋转增量。最终头部的响应旋转限制为 0.012 rad,约 0.69°。

这不是一个通用的“安全转角”。它是针对当前网格、贴图和正面展示方式选出的限制;换一套模型,要重新检查。

方向要来自入口的实际位置

另一个问题藏在布局里。桌面和手机会改变物品位置,如果用分类名称硬编码左右方向,入口移动之后,人物仍可能朝旧方向响应。

现在计算的是物品中心与人物中心的水平位置关系。窗口尺寸变化时重新计算;点击或聚焦时再用当前位置确定方向。分类名称不参与左右判断。

响应也有明确的结束:悬停、聚焦停留约 1.8 秒,点击停留约 2.2 秒,然后回到初始姿态。快速切换从当前姿态继续过渡,不把上一次的角度累加进去。

这样,读者选中的分类可以一直保留,人物的动作则会自然结束。文章筛选和人物姿态各自管理。

怎样确认这次调整有效

我没有只看一个停住的画面。2026-10-14 的动作检查留下了 55 张姿态截图,覆盖连续过渡、回归、快速切换和手机响应。这批采样记录中的最大头部旋转约为 0.474°,没有超过设定上限。

数值检查与画面检查分别回答不同问题:前者检查旋转有没有越界;后者检查脸颊、眼镜和托腮接触处是否自然。即使数值通过,画面仍可能有贴图问题。

检查内容 关注点
连续切换入口 方向是否正确,角度是否累计
长时间悬停与聚焦 响应能否结束并回归
不同页面宽度 入口移动后,方向计算是否更新
最终骨骼姿态 是否计入身体父节点的影响
实际渲染画面 脸颊、眼镜、手与头的接触是否异常

这一轮保住了小幅互动,也留下了清楚的下一步:如果需要真正看向右侧,就要补齐侧脸材质和眼部绑定,而不是继续放大现有旋转。

这次最有用的经验,是先确认素材能够支持的动作,再决定交互幅度。动作越小,越需要仔细检查它究竟在回应什么。

相关资料

继续阅读 · 把一道乘法题做成十五秒视频