首页 / 全部技能 / 设计 / threejs-animation
设计 · iart-ai/webgl-animation-skills

threejs-animation

This skill should be used when the user asks to "build a 3D hero section or WebGL background", "animate a Three.js scene", "play or crossfade GLTF animation clips", "move/lerp the camera or link it to scroll", "render thousands of objects with InstancedMesh", "set up React Three Fiber (R3F) motion", "add bloom/DOF post-processing", or "keep a Three.js/R3F animation smooth and leak-free (dispose geometries/materials/textures, free GPU memory on unmount)". Covers scenes, render loops, camera moves, GLTF AnimationMixer, instancing, scroll-linked 3D, R3F, and animation performance/disposal.

风险提醒:蓝色 · 知晓即可AI 侦查报告
作者 iart-aiGitHub iart-ai/webgl-animation-skills ↗Stars 14许可 MIT(仓库根 LICENSE 为 MIT License / Copyright (c) 2026 iart.ai;.claude-plugin/plugin.json 亦声明 "license": "MIT")commit 50697d659f
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

实现原理是三组 API 纪律加一条显存回收纪律:帧率无关(乘 dt)、用 setAnimationLoop 而非裸 rAF、以及把 GPU 资源生命周期当作一等公民。

skills/threejs-animation/SKILL.md
Use `clock.getDelta()` to make motion frame-rate independent (multiply rates by `dt`), and `setAnimationLoop` (works with WebXR and pauses on tab blur) instead of raw `requestAnimationFrame`.
注:这里在做什么:讲清「为什么不用裸 rAF」「为什么乘 dt」——这两条决定后面所有动画代码的形态。

GLTF 播放走 AnimationMixer,关键是「用 delta 更新 mixer」;交叉淡化用 crossFadeTo(warping=false 为线性权重),单次动作用 LoopOnce + clampWhenFinished + finished 事件。

skills/threejs-animation/SKILL.md
Load a model, play clips through an `AnimationMixer`, and **update the mixer with delta time** every frame.
注:这里在做什么:给出 clip 播放的完整生命周期(load → clipAction → crossFade / one-shot),是 three 里最容易写错的一段。

相机运动用指数阻尼插值 lerp(goal, 1 - exp(-lambda*dt)) 而不是固定系数,从而任意帧率下阻尼手感一致;滚动只改目标位,由阻尼平滑,曲线飞行走 CatmullRomCurve3 + getPointAt。

skills/threejs-animation/SKILL.md
Smooth camera follow uses exponential interpolation toward a target. Frame-rate-correct damping:
注:这里在做什么:把「帧率正确」从口号落到公式,并配曲线路径的实现入口。

大量对象用 InstancedMesh 换一次 draw call,逐实例矩阵 setMatrixAt;每帧更新要切 DynamicDrawUsage,颜色走 setColorAt 并置 needsUpdate。

skills/threejs-animation/SKILL.md
One draw call for thousands of identical meshes. Set per-instance matrices (and optional colors).
注:这里在做什么:把「数千对象」的性能路径固定成 API 组合,并交代每帧更新的必要开关。

R3F 分支以 useFrame(state, delta) 驱动,并把 dpr 上限写进 <Canvas dpr={[1, 2]}>;模型/动画交回 useGLTF、useAnimations,弹簧与滚动按需引 @react-spring/three、drei ScrollControls。

skills/threejs-animation/SKILL.md
Drive animation with `useFrame`; it receives `state` and `delta`.
注:这里在做什么:同一套纪律在声明式渲染器里的对应写法(useFrame + dpr 上限)。

显存回收是文档核心:解释 GC 释放不了 GPU buffer/texture 的机制,给「该 dispose 什么、什么不用」的判据,再给含材质数组与所有贴图槽的整套遍历。

skills/threejs-animation/SKILL.md
GPU resources (geometries, materials, textures, render targets) live on the *GPU*, not the JS heap. The garbage collector frees the JS objects but **cannot free the WebGL buffers/textures they uploaded**.
注:这里在做什么:回答「为什么黑画布 / CONTEXT_LOST_WEBGL」,并点破 scene.remove 不释放任何 GPU 资源这一常见误解。

R3F 的泄漏边界被切开:JSX 声明式创建的资源卸载时自动 dispose,imperative(useMemo/ref/loader 里 new 出来)的不会,必须在 useEffect 清理里手动 dispose;并用 renderer.info.memory 做 10 次挂载/卸载的基线回归来证实。

skills/threejs-animation/SKILL.md
Verify with `renderer.info.memory` (R3F: `useThree().gl.info.memory`): mount/unmount 10x; if `geometries`/`textures` does not return to baseline, something leaked.
注:这里在做什么:把「是否泄漏」变成可跑的量化检查,而不是靠猜。

2核心能力

01最小场景 + 渲染循环骨架(camera 参数、DPR 上限、resize、setAnimationLoop、dt 驱动旋转)
02GLTF 动画:AnimationMixer 播放、crossFadeTo 交叉淡化、LoopOnce + finished 事件
03相机阻尼跟随与滚动驱动 3D(含 CatmullRomCurve3 曲线飞行)
04InstancedMesh 批量渲染(逐实例矩阵 + 逐实例颜色 + 每帧 needsUpdate 的性能开关)
05React Three Fiber 运动:useFrame、dpr 上限、useGLTF/useAnimations、drei ScrollControls 与 springs
06性能清单:DPR 上限、几何/材质复用与静态几何合并、少用实时光照阴影、优先材质动画而非搬几何
07GPU 显存回收:disposeObject 遍历(材质数组 + 所有贴图槽)、renderer.dispose + forceContextLoss、R3F useMemo+cleanup、共享资源 dispose={null}
08确定性截图 harness(?t=N 钉住 elapsed,mixer 用绝对时间 setTime)与完成前清单

3外部依赖

类型依赖
clinpx playwright screenshot(验证回路:截 file:// 页面冻结帧)
cli仓库根共享脚本 scripts/seek-shot.sh、scripts/contact-sheet.sh(不在 skill 目录内)
cliffmpeg / ffprobe(contact-sheet.sh / probe-mp4.sh)
packagethree + three/addons(GLTFLoader 等),产物期经 importmap 从 CDN 取
packageReact Three Fiber 生态(@react-three/fiber、drei 的 useGLTF/ScrollControls、@react-spring/three,以及 postprocessing 的 UnrealBloom / DepthOfField)

4风险提醒 风险提醒:蓝色 · 知晓即可

风险提醒:蓝色 · 知晓即可
  • 验证回路依赖 npx 远程获取 Playwright 与 Chromium — 内联 `npx playwright screenshot` 与仓库根 seek-shot.sh(`npx -y playwright screenshot`):首次运行安装远程包并下载浏览器二进制,版本不锁定。
  • 无头软件渲染下 GPU 相关结论不可直接推广 — swiftshader 可以出图,但帧时间、显存占用与泄漏表现与真机 GPU 差异明显;renderer.info.memory 回归应在目标设备复跑,否则可能得出错误结论。
  • R3F/后处理分支引入较重的第三方依赖面 — @react-three/fiber、drei、@react-spring/three、postprocessing 由用户项目安装;版本漂移会改变 useFrame/dpr 行为与 dispose 语义,建议锁版(本 skill 不含 lockfile)。
  • 产物期从 CDN 取 three 与远端 GLTF/贴图,版本与来源均未锁定 — 输出契约要求 importmap 指 CDN;模型/贴图若来自第三方 URL,长期在线发布需自托管、固定版本并确认许可。
  • 仓库根脚本不在 skill 目录内 — 只安装 skills/threejs-animation 时 scripts/seek-shot.sh 引用悬空;需自行改用等价 playwright/ffmpeg 命令。
风险提醒:蓝色,知晓即可。判级对象=skill 自身目录,只有 SKILL.md 与两份 markdown reference(另有 0 字节 README.md):无自带脚本、无凭证读取、无端点调用、无用户素材外发;交付物是本地单文件 HTML(或用户自己的 R3F 项目)。执行期只涉及本地工具(`npx playwright screenshot` 截 file:// 本地页面、ffmpeg 拼图),产物期 HTML 经 importmap 从 CDN 取 three / three/addons 属浏览器端拉取(按范式「产物期引用不判级」,记入 reason)。注意点:① `npx playwright` 会拉取远程包并首次下载 Chromium(供应链接触面,版本不锁定);② scripts/seek-shot.sh、scripts/contact-sheet.sh 位于仓库根,单装 skill 目录会引用悬空;③ WebGL/GPU 前提:无头 swiftshader 软件渲染下帧时间与真机差异明显,泄漏回归应在本机 GPU 上复跑;④ R3F 分支声明了若干第三方包(fiber/drei/react-spring/postprocessing),由用户项目自行安装与锁版。均不满足黄色(无常规网络外发)与橙色特征;经全仓扫描确认无关沙箱/关 TLS/绕过自动化侦测等红档行为。

5第二遍独立确认

  • [ok] 「skill 目录内无脚本、无 3D 资产」是否成立 — 文件清单实证:目录内只有 SKILL.md、README.md(0 B) 与两份 markdown reference;无 .glb/.gltf/.hdr/贴图,也无 package.json 或构建配置。引用到的 scripts/*.sh 属仓库根资产。
  • [ok] 凭证/环境变量读取是否存在 — 本仓全仓正则 `process.env|API_KEY|TOKEN|SECRET|Authorization` 零命中;credential_reads 为空成立。
  • [ok] 是否有更高的触发条件被漏掉(红档特征) — `sandbox|automationcontrolled|no-verify|stealth|bypass|ignoreHTTPSErrors|dangerously` 全仓零命中;无任意代码执行面(交付物在浏览器沙箱内运行用户自己的场景代码)。
  • [ok] 「显存 GC 释放不了」的解释与处置是否自洽 — 文档先讲机制(GC 释放 JS 对象但释放不了上传的 WebGL buffer/texture),再给「该 dispose / 不用 dispose」清单,再给 disposeObject 遍历(含材质数组与 for…in 贴图槽),三者互证;scene.remove 的误解也单独点破:'it frees **nothing** on the GPU'。
  • [ok] R3F 自动 dispose 的边界声明是否有可验证手段 — 声明式自动 dispose vs imperative 泄漏的分界写得很具体,并要求 renderer.info.memory 挂载/卸载 10 次回归;references/resource-disposal.md 另附完整泄漏案例与 <DisposeOnUnmount> 方案,属可执行而非口号。
  • [ok] 冻结 harness 与 mixer 的配合是否写对(易错点) — harness 段用 `mixer.setTime(elapsed)` 并注释 'setTime is absolute, not delta',与循环里 `mixer.update(dt)` 的增量语义区分开,说明作者意识到差异,声明可信。

6结论

  • 把显存回收当主线讲:机制 → 判据 → 遍历代码 → 量化回归,正面回答黑画布/CONTEXT_LOST 类症状
  • 关键 API 都配反面提醒(裸 rAF、scene.remove、R3F 只自动 dispose 声明式资源)
  • 帧率正确性落到公式(指数阻尼 1 - exp(-lambda*dt)),不是「乘个 dt」的口号
  • GLTF 生命周期覆盖到交叉淡化与单次动作的收尾事件,可直接照抄
  • 两份 reference 分治,回收篇细到贴图槽、render target 与 HMR 安全
  • 性能给优先级与取舍(DPR 上限是最大收益;材质动画常比搬几何更划算)
  • 适合:适合做 3D hero / WebGL 背景 / 产品查看器 / 滚动联动 3D / GLTF 角色播放 / 数千对象实例化,以及 R3F 项目的动画与性能治理;尤其适合排查「动画跑得动但显存越用越多」「切换路由后黑画布」这类遗留问题(泄漏回归与处置工具直接可用)。输出为可直接打开的单文件 HTML,也适合作为团队内的 three 性能/回收规范文本。
    不适合:不适合:① 需要离线渲染/电影级画质的视频产出(这里是实时 WebGL);② 完全无 GPU 且要求接近真机性能的验收环境(软件渲染会失真);③ 想要自带完整 3D 资产与模型的项目(skill 只给代码方法与参考,不含模型/贴图);④ 把 CDN 版本与第三方包视为不可接受风险的严格供应链场景(须自托管并锁版);⑤ 只安装 skill 目录、指望仓库根 scripts/ 存在的环境。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-28
    方式 A · 人下载镜像包下载 threejs-animation.tar.gz
    sha256: de5e7ad51ab285c7…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit 50697d659f;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库iart-ai / iart-ai/webgl-animation-skills
    Stars14
    最近推送2026-06-22
    本 skill commit50697d659f
    许可MIT(仓库根 LICENSE 为 MIT License / Copyright (c) 2026 iart.ai;.claude-plugin/plugin.json 亦声明 "license": "MIT")
    本站信息
    收录日期2026-09-06
    分类设计
    侦查报告AI 侦查 · 2 遍 · 2026-09-06
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。
    同分类邻近