☰
editonny 3D场景运行时完整指南:基于Three.js的动效场景如何实现任意时间寻址
2026/11/5 5:12:15 网站建设 项目流程

【免费下载链接】editonny

Local video editing through conversation. Created by Matheus Gomes.

项目地址:https://gitcode.com/gh_mirrors/ed/editonny
点击查看免费下载

editonny 是一个本地运行的对话式视频剪辑工具(开源、免费),你只需用自然语言描述剪辑意图,它就能自动完成剪辑、字幕与动效合成。本文聚焦它的 3D 场景运行时:动效画面基于 Three.js 构建,核心能力是"任意时间寻址"——把场景拖到时间轴上任意一秒,画面都能精确重放到那一刻。

一、什么是"任意时间寻址"

普通网页动画通常靠"每帧累加"推进:这一帧旋转 1°,下一帧再转 1°。这种写法在预览时没问题,但一旦剪辑工具需要跳转到时间轴任意位置重渲染(逐帧抽帧、seek 预览、渲染导出),累加状态就会算错——跳过去的那段时间被"欠账"了。

editonny 的 3D 场景反其道而行:

  • 场景构建时返回一个纯函数draw(time):输入时间 → 输出该时刻的完整画面;
  • 官方场景模板明确要求:"Never accumulate frame-to-frame state: seeking to the same time must produce the same frame"(禁止跨帧累积状态,seek 到同一时间必须得到同一帧)。

这条规则写在场景开发文档 scenes/README.md 中,是 editonny 3D 场景的"宪法"。它带来一个直接的好处:预览画面与最终导出帧逐帧一致,所见即所得。

二、场景骨架:three-scene.js 门面与 engine 模块

3D 场景的统一入口是 three-scene.js(facade 门面文件),它把整个运行时 API 一次性导出:

类别主要 API作用
渲染核心initialize初始化 WebGL 渲染器、相机、环境光照,返回draw
时间函数clamp/mix/smooth/interval/word/moment时间区间、缓动、口语词锚点
相机函数orbit/mixPose/frameCamera/fittingDistance轨道相机与自动取景
几何/材质plate/box/cylinder/volumeText/loadModel/mediaTexture实体、体积文字、GLTF 模型、贴图

底层 Three.js 使用本地固定版本的资源(three.module.min.js、GLTFLoader.js、RoomEnvironment.js),放在 assets/three/ 目录,保证离线渲染和版本一致性。

三、draw(time):让"重放"成为可能的核心 API

打开 stage.mjs 可以看到initialize的收尾逻辑(核心片段):

const draw = (t) => { const tt = clamp(Number(t) || 0, 0, DUR); // 时间被钳制在 [0, 时长] 内 update(tt); // 场景状态完全由 tt 推导 for (const tx of textures) tx.update(); // 同步贴图 renderer.render(scene, camera); // 渲染该时刻画面 };

要点只有两个:

  1. 一切状态都是时间的函数——物体旋转角、阴影位置、标签透明度,全部由传入的t计算得出,而不是上一帧残留;
  2. 时间做钳制,seek 超出范围也不会渲染异常帧。

场景构建阶段还会做一次"预演体检":以 30fps 采样遍历整个时长,检查相机路径是否会"穿模"进入物体内部,命中就写入警告(camera enters "..." at xx s),而不是等到导出时才发现。

口语词锚点:动画跟着"人话"走

time.mjs里的word和moment工具支持用口播词而非绝对秒数定义动画时机,例如内置场景 volume.html 中:

turn: { word: "just", standard: 0.8 }, // 主角说到 "just" 时开始旋转

若转写中找不到该词,回退到standard的秒数。这让 3D 动效天然对齐语音节奏——正是对话式剪辑最需要的能力。

四、相机取景:orbit 与 fittingDistance

camera.mjs 把"构图"变成了数学问题:

  • orbit(camera, pose):用目标点 + 距离 + 方位角 + 仰角(球坐标姿态)确定相机,mixPose可在两个姿态间平滑插值;
  • fittingDistance:给定物体包围盒,用二分搜索求出"物体恰好完整落在安全区"的相机距离,自动取景不再靠手调;
  • frameCamera:把视口对齐到画面安全区(safeArea),适配 9:16、4:5 等竖版格式。

五、场景如何接入时间轴

每个场景 HTML 把一个暂停的 GSAP 时间线注册到window.__timelines[id],并用一个代理时钟驱动 3D 渲染(见 volume.html):

const tl = gsap.timeline({ paused: true }); tl.fromTo(clock, { t: 0 }, { t: DUR, duration: DUR, ease: "none", onUpdate: () => draw && draw(clock.t) }, 0); window.addEventListener("hf-seek", () => { if (draw) draw(clock.t); });

播放/seek 由 HyperFrames 运行时驱动:它跳到哪一秒,就把时间线推到哪一秒,draw(clock.t)立即重渲染——任意时间寻址就此闭环。自定义场景只需在 project.json 中注册文件与起止时间({"scenes": [{"file": "compositions/scenes/xxx.html", "start": 2, "end": 7}]})即可。

六、质量如何保障

  • 构建期:python3 build.py hf lint/hf check校验组合结构(见 project-template/README.md);
  • 诊断面板:window.__scene3d[id]暴露 ready 状态、警告列表、Three.js 版本与构建耗时;
  • 自动化测试:tests/three-engine.test.mjs 校验门面 API 完整性与时间函数边界值,scripts/smoke_three.mjs 在真实浏览器里跑通实体、体积文字、贴图与标签的完整渲染冒烟测试。

官方参考文档 references/3d.md 还强调:只有真实几何、光照、相机与遮挡才算 3D,"平铺层 + 视差"只能算 2.5D。

七、小结

editonny 的 3D 场景运行时可以概括为一句话:用draw(time)纯函数取代逐帧累加,用口语词锚点取代绝对时间,用本地固定的 Three.js 保证确定性渲染。这套设计让对话式剪辑里的 3D 动效既能被任意 seek、又能被逐帧精确导出,是"本地、可复现、所见即所得"理念的典型落地。

想动手实践?可参考 project-template 构建文档 与 3D 参考指南,从内置场景 volume / exploded / path / screen 出发,逐步替换成自己的几何体与台词锚点。

【免费下载链接】editonny

Local video editing through conversation. Created by Matheus Gomes.

项目地址:https://gitcode.com/gh_mirrors/ed/editonny
点击查看免费下载

相关推荐

上一篇:远程工作者的职业发展路径:在中国科技公司的27个成长机会
下一篇:终极指南:如何构建ElasticJob跨集群调度联邦架构

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

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

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

立即咨询