Communitygithub.com

Handkit

为代码生成的视频制作解剖学精确的3D手部和前臂动画(支持 fframes、HyperFrames/three.js、Remotion)。适用于需要手势、手语、计数、指向、握手、拥抱、做出反应或根据参考片段复现手部编舞的视频场景,支持写实、卡通、蜘蛛侠、双城之战或粘土风格,多种肤色,任意人数。

Handkit 是什么?

Handkit 是一个基于 JSON 的 3D 手部动画工具套件,它通过定义姿态和片段让用户以纯粹的代码方式生成解剖学精确的 3D 手部和前臂动画。该工具的核心功能将关键帧姿态转化为平滑自然的动作(整合了弹簧、手指级联、跟随动作和空闲动画),并通过内置渲染引擎输出视频或逐帧图像。其关键特点在于完全确定性——相同的片段始终产生完全一致的帧序列,这为可复现的生产管线提供了坚实基础。Handkit 支持 fframes、HyperFrames/three.js 和 Remotion 等主流代码视频框架,并提供丰富的内置姿态库(约 50 个命名手势,如拳头、点赞、OK、胜利手势等)、接触求解器(用于实现指尖触碰到手指交叉)、多人手部交互(包括握手、击掌、拥抱等)以及多种视觉风格(写实、卡通、蜘蛛侠、双城之战、粘土)和肤色配置。工作流遵循“从库开始 → 编写片段 → 检查 → 预览 → 渲染”的步骤,并内置了视频对比工具用于复现参考片段。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ayushmaniar/3d-accurate-hands/tree/HEAD/plugin/skills/handkit

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Handkit 是做什么的?

手部动画本质是 JSON:一个姿态由关节角度和位置组成;一个片段是随时间变化的关键帧序列;核心引擎将这些转化为自然的运动(弹簧、手指级联、跟随动作、空闲动画),并由渲染引擎绘制。一切都是确定的:相同的片段产生完全相同的帧序列。

下方 HANDKIT 指 Handkit 文件夹(仓库根目录)。在它所在目录下执行命令。

**首次使用:**如果 Handkit 文件夹还不存在,请先设置(需要安装 git、Rust 和 FFmpeg;首次构建需要几分钟,建议在后台运行):

HANDKIT=${HANDKIT:-$HOME/.handkit}
[ -d "$HANDKIT" ] || git clone --depth 1 https://github.com/Ayushmaniar/3d-accurate-hands "$HANDKIT"
cd "$HANDKIT" && cargo build --release -p handkit-cli
(cd starters/fframes-clip && cargo build --release)    # 仅当你需用 fframes 渲染视频时才需要
H=$HANDKIT/target/release/handkit          # CLI(只需运行一次 cargo build --release)
P=$HANDKIT/starters/fframes-clip/target/release/fframes-clip   # 视频播放器
A=$HANDKIT/assets                          # hand_R.glb, hand_L.glb(handkit mesh 写入后生成)

工作循环(请按顺序执行)

  1. 从库开始。 $H gestures 列出约 50 个命名手势及其描述(如 fist、point、ok、thumbs_up、peace、spread_palm、pinch、heart_hands、camera_frame、handshake...)。在手上使用 "from": "ok" 可快速获取该手势的形状,这几乎是零成本的。只需为你需要的不同之处编写关节角度。
  2. 编写一个片段(最小化示例,30 fps):
    { "version": 1, "fps": 30,
      "camera": { "position": [0, 0.12, 0.6], "target": [0, 0.1, 0], "fov": 30 },
      "look": { "style": "realistic", "skin": "medium" },
      "keys": [
        { "t": 0,   "hands": { "right": { "from": "fist",
            "place": { "wrist": [0, 0, 0], "palm_facing": [0, 0, 1], "fingers_toward": [0, 1, 0] } } } },
        { "t": 0.8, "hands": { "right": { "from": "spread_palm" } } },
        { "t": 1.6, "ease": "snappy", "hands": { "right": { "from": "point" } } } ] }
    
    每个关键帧默认继承前一个关键帧的状态:只写你需要改变的部分。t 表示姿态到达的时间;move 表示移动持续的时间(0.12 表示快速动作);"pass": true 使动作流经该关键帧而不停留。使用以下方式在画面中放置手部位置: "place": {"screen": [x, y], "depth": 0.5, "palm_facing": .., "fingers_toward": ..} (x, y 是画面比例,0,0 为左上角),并通过 "elbow_screen": [1.1, 0.9] 让手臂从画面边缘伸入。
  3. 检查:在渲染前运行 $H check clip.json(检查接触保持、手指交叉、速度、抖动、构图、肘部是否在画面内)。根据输出信息修复问题;它明确指出了存在问题的关键帧编号。
  4. 预览(小且快速):$P --clip clip.json --assets $A strip -n 12 生成 strip.png(查看它)。frame 2.5s 生成一帧完整图像。
  5. 渲染:$P --clip clip.json --assets $A render -o out.mp4(1920x1080,实际时长秒)。竖屏 1080x1920:使用相同的命令,但将 fframes-clip 替换为 $HANDKIT/starters/fframes-clip/target-portrait/release/fframes-clip。背景:--background "#1d1f24",聚光灯:--spotlight 0.5,0.45,0.35,#3a3f48。

你还能做什么

  • 接触求解:"goals": [{"touch": ["right.thumb.tip", "right.index.tip"]}],然后运行 $H solve pose.json 将精确满足接触条件(若无法满足则退出码为 2)。瞄准:{"aim": "right.index", "at": [x,y,z]}。
  • 视觉风格:顶层 "look" 支持样式 realistic | toon | spiderverse | arcane | clay,肤色 light | medium | tan | brown | dark | #rrggbb,以及 outline、motion_blur(子帧)。也可在播放器上指定:--look spiderverse,skin=brown。
  • 前臂末端:骨骼止于肘部。当肘部可能露出时,使用 "look": {"arm": "fade"} 或 {"arm": {"sleeve": "#1e2a4a", "length": 0.08}}(卷起的袖子)。
  • 将 UI 与手部同步:$H track clip.json --site right.index.tip 打印每帧中指定点在屏幕上的位置(帧比例坐标),例如用于让按钮响应点击。
  • 多人:手部名称如 ana.right、ben.left(可使用任意名称);"people": {"ana": {"look": {"skin": "dark"}, "scale": 1}}(scale 0.75 表示儿童手部)。手部之间会相互推开而非穿透(设置 "collide": false 允许重叠)。
  • 握手:接触目标 {"grip": ["ana.right", "ben.right"], "style": "handshake"};支持风格:handshake、interlaced、cupped、high_five、fist_bump、pinky。在连续关键帧中使用相同的 grip 会使双手一起移动,跟随手会延迟几帧跟随。
  • 单人的双手:可通过 touch 目标实现合掌、拍手或摆出取景框手势。

复现一个参考视频

首先研究它:ffmpeg -i ref.mp4 -vf fps=4,scale=480:-1 f%03d.png 并查看每一帧。为每个可见的事件设置一个关键帧;使用 screen 放置手部,用 elbow_screen 瞄准前臂;根据参考帧的时间调整关键帧时间。对比:运行 python $HANDKIT/tools/motion/compare.py ref.mp4 out.mp4 cmp(生成一个包含两者同时刻帧的对比图,以及一个并排的 MP4 视频)。

需要更多信息时

运行 $H explain(约定)、$H explain clips、$H explain looks、$H explain <参数>(例如 thumb.cmc_rot),或查看 $HANDKIT/docs/POSE_SPEC.md。只阅读你需要的部分。原始关节范围:手指 mcp_flex -30..95,pip_flex -5..110,dip_flex -10..85,mcp_abd 约 -15..25;手腕 wrist_flex -80..85,wrist_dev -35..35。

经验法则:先从库中选手势;关键帧要少、时间要准(真实手部移动约 0.2-0.6 秒并保持);渲染前先检查;看缩略图 strip 而非整个视频;保持文件小型化。

相关技能