敦煌 · 入壁 / SOURCE ENGINEERING REVIEW · 2026-10-23打开实时动态候选 ↗版权声明

从像素到动态世界:完整源码技术拆解

《清明上河图》并非“整张古画套一个 Three.js 特效”。真正的工程是:独立图层资产、程序化三维、二维约束蒙皮、统一叙事时钟,以及严格的遮挡与资源调度。

本报告采用 REA 的“证据—机制—边界—独立重建”方法。因为已取得完整的选定源码范围,按技能要求直接审查仓库,不对源代码伪装做二进制反编译。上游没有运行;敦煌新实现另有真实浏览器证据。两种证据不可混用。

01 / 研究范围与可信度

对象为 xianxie6/qingming-riverside,来自用户提供的微信文章。固定版本 c575d242194fddafe33ec70dd01b860a75f09686,不是泛指所有同名项目。

范围 已完成 不能升级成的结论
文件级 250份源码、测试、文档和配置,逐文件长度与SHA-256;83个src模块盘点 不是逐个资产许可审计;不包括上游画片、音频和vendor实现
核心路径 入口、时钟、相机、GPU粒子、几何、水层、人物、遮挡、天气、加载、发布的深读 不是穷尽每个分支,也不是完整安全审计
非默认模块 探索、店铺、节庆、扩展街区职责和关键实现扫描;巨大坐标表只查结构 不宣称每个手工坐标都正确
测试 45个上游测试文件的内容和局限审查 本次未执行上游测试,不把桩测试当真实GPU或FPS
重建 独立敦煌WebGL粒子、相机、尘粒、丝带、反射及交互,原图图库保留 不是完整三维洞窟,也未完成逐人物骨骼动画

逐文件证据清单 · 视觉深审全文 · 系统深审全文与70模块表 · 本地验收记录(未随公开源码分发)

02 / 真正的系统架构

固定版本源码架构 / 原创示意,非上游截图输入:滚轮 / 拖动 / 按键 / 时间轴 → 统一进度与场景时钟① 真三维穿越构件实例 / 船体 / 受限透视相机镜像反射 / 阴影 / 最终纸墨合成② 2.5D 粒子庭院位图背景 / 采色浅浮雕人物GPU 聚散 / 排斥 / 有限视差③ 混合街市Canvas2D 最终合成 / 图层遮挡内部 GPU 人物网格 + Three 水层公共工程:并发加载 · 可见区缓存 · DPR预算 · 降频更新 · 取消/销毁 · 静态回退
建筑背面、人物完整体积与任意自由镜头不是此架构自动拥有的能力。

从入口到画面的调用链

index.html → crossing.js → crossing-three.js → motion / world / details / courtyard / hero / water → renderer。穿越结束通过 AtlasTour.enterBridge() 进入街市;不是切回同一张放大图片。

街市则是 atlas.js → dynamic-loader.js → scene.js → world / movement / inhabitants / districts / weather / seasons / water → Canvas2D。人物内部还有原生WebGL PeopleMesh,因此“最终是2D”和“内部用了GPU”同时成立。

历史 crossing-tunnel.js 未被当前主链导入,也不在默认发布白名单。变量名 tunnel 在当前版本实际装载庭院,不能只看名字猜效果。

03 / 核心算法,逐层拆开

技术 实现机制 定位与工程含义
叙事时间轴 target/current/playing/held分离;dt封顶;指数追踪,自动全程设计约50秒 src/crossing-motion.js:16-25;刷新率不应改变叙事速度
程序几何 拱桥构件、甲板、栏杆实例化;船体截面拼面,篷顶管线 src/crossing-world.js:36-150;有真实坐标、遮挡和体积,但远岸仍是贴图平面
粒子人物 透明像素采色;桌面80k/移动24k低面球实例,每球20顶点/36三角形;浅深度扰动 src/crossing-hero.js:3-79;不是人体重建,不是标准骨骼数字人
鼠标扰动 世界坐标距离核衰减,局部排斥;聚拢、旋动和burst共享着色器 同上;不是CSS transform,也不是物理粒子碰撞求解
角色走路 路程驱动步态,两骨IK、脚底接触、躯干/袍/腿分区变形 src/movement.js:48-200;得先有角色alpha层和手脚锚点
人物GPU 静态纹理Map复用,动态顶点bufferSubData;另有Canvas仿射网格回退 src/inhabitants.js:6-69,350-521;二维绘画网格而非三维骨架
反射与合成 低分辨率镜像相机、斜裁剪;反射3帧/阴影6帧更新;庭院另target混合 src/crossing-three.js:45-126;多pass有成本,不能只统计一次render
水流 相位平流噪声混合、正弦波、差分法线;瀑布反解下落时间 src/water-three.js:7-122;艺术近似,非CFD
内容行为 六组编排故事、渡船阶段机、避让clock、牵绳力反馈 src/street-life.js、src/world.js、src/bridge-event.js;不是NPC各自调用LLM
昼夜四季 雨/湿/风分通道,逐人开伞;灯窗配准;季节切换背景和衣服资源 src/weather.js、src/night.js、src/seasons.js;不是整图滤镜

关键公式是通用图形/动画方法,而非受限代码的转抄:平滑阶跃为 t²(3−2t);指数追踪权重为 1−exp(−k·dt);排斥按距离平方指数衰减;二维腿部IK由两段长度和脚目标共同约束。源码内的参数是绘画世界尺度,不能冒称文物测量值。

真正费工的,是图层与遮挡

主画面顺序:建筑缓存 → 湿地/水面 → 夜色 → 透明前景 → 船与居民 → 家具/行人遮挡 → 瀑布 → 渡船客与舷边 → 环境船 → 雨棚/风物/蒸汽/雨雪 → 最终灯饰。

只对整张壁画做UV扭动,无法表现人物在桌后、船客在舷边内、手握住桨。要复现这种局部真实动作,需要逐母题拆层、接触点、蒙皮权重、补底板和遮挡;目前敦煌十张整幅资源尚不具备这套人物层资产。报告不将整幅粒子运动冒称“人物已经舞动”。

04 / 发现的问题与证据门槛

高可信静态缺陷,运行影响未测: src/crossing-water.js:13 插入的共享GLSL引用 noise()、bankAt(),但该过场片元着色器中未见相应定义;29行 shadeRiver 使用3个实参,共享定义要求4个。应针对真实GPU编译/链接验证,而不是只跑JS测试。没有运行上游,不能据此断言作者线上必定黑屏,也不能反过来宣称上游效果已测正常。

其他边界:仓库存在不等于发布启用;装饰数字不等于真实遥测;访问计数不是去重UV;受限视差不等于自由漫游;维护45个测试文件不等于45项实机验证。文章中的人数、FPS、加载秒数、传播量与“OpenAI点赞”未作独立证实。

05 / 加载、性能与生命周期

资源并发请求但经典脚本保序执行;等待ready/error屏障。可见街区优先、promise去重、超时失败可重试;建筑缓存带视区边界余量,未备好保留最后完整帧。四季切换带revision防止迟到请求覆盖当前选择。

上游预算为80万/140万渲染像素、DPR上限1/1.25、反射256/512、阴影512/1024;至少2秒30帧采样且平均帧耗超过26ms才降级。这是策略,不保证所有手机60FPS。销毁取消RAF、解绑监听、释放GPU;异步请求取消仍有局部改进空间。

06 / 发布与后端

npm run build 的CLI缺省采用 crossing 精简profile,build:all才全量。默认移除探索、孙羊店、中秋/烟花和扩展街区;不能将仓库全部功能算进线上首屏。源码含Three vendor,但package.json不直接给出其版本,不能硬猜。

Worker主要提供可选 /api/visits POST,以D1 UPSERT记请求数,其他交给静态ASSETS。没有以实时大模型驱动主动画的证据。GitHub工作流跑CI、构建、dry-run后发布;本次未执行上游部署脚本,避免向作者仓库写入。

07 / 敦煌 V0.4「空远」:自然度修正与全屏观画

用户实测认为V0.3动作不自然。根因在于面部核心也处于顶点权重梯度中,五官相对位置会改变;镜头持续余弦推拉、重复画片视差与过多装饰又加重了整张纸漂移的感觉。

V0.4的壁画几何保持平面不变。片元根据人工椭圆与枢轴选择唯一角色,核心采用同一个逆向刚体采样,羽化放在外围;同源曲线形成休息—缓起—停留—缓回,关节角度小于0.018弧度。衣带保留固定端,末梢才有更明显的微风。默认相机固定、整幅适配,导览点/时间轴/特写保留为主动观看;移除镜像、浮石与重复画片。它仍不是拆层补底或完整骨骼,外围接缝与大幅运动的限制没有凭空消失。

空远 / 少动一点,留白多一点未改动的原图等距核心 + 外围羽化静驻镜头 + 全幅适配同一场景时钟:有停顿的微动作 / 84秒原创稀疏音符 / 6.5秒程序混响 / 用户主动开启音乐首屏100dvh · 详细控制折叠 · 保留无限画布同款合作洽谈
原创实现示意,不是上游截图或文物测绘。

原创禅意轻音乐不使用佛曲录音、经文或采样包。声音由振荡器、稀疏音符与确定性双声道混响产生,音乐默认关闭。19项Node检查与真实GPU、连续帧、暂停、音频RMS、视口几何和扫码弹窗分别验证;物理手机、听感与用户视觉验收仍独立保留。版权及公开代码不分发壁画扫描的边界见COPYRIGHT.md。

本地历史运行截图不随公开源码再分发;本节是技术记录,不作为当前视觉验收。

V0.3 历史基线(已被用户拒绝自然度,不是当前验收)

默认进入反弹琵琶,中央舞者头颈、躯干与上举前臂分别按人工定位枢轴作小幅旋转,披帛和衣褶使用另一组柔边局部纹理/深度扰动。局部关节不受环境保护掩码禁动;脸部保护区禁止通用云水UV扰动,但不承诺网格权重内五官每个像素绝无形变。这是完整不透明画片上的局部网格演绎,不是精细alpha人物层、三维人体骨骼、独立步态或真实拨弦。

本地历史运行截图不随公开源码再分发;本节是技术记录,不作为当前视觉验收。

十幅共35个局部材质区、6幅8处局部关节;九色鹿颈首、菩萨/主尊微倾、维摩诘头颈与帷幔,各有定位和节拍。五台山与复杂三层/群像四幅保留静止人物,使用云水、山林层次和分段运镜。六类材质机制在十个profile中组合,不把十个类型名称冒充十套完全不同的渲染算法。矿彩52k/窄屏22k是可选模式,不再是默认唯一特效。

本地历史运行截图不随公开源码再分发;本节是技术记录,不作为当前视觉验收。

文件/层 独立机制 本轮证据与边界
mural-scenes.mjs 人工UV区域、枢轴、面手保护、导览停点和节拍 十图配置自检;不是自动分割或考古测绘
mural-effects.js 密网格柔权局部旋转,衣带/云/水/圆光/帷幔/明暗六类Shader 十图实际GPU链接通过;羽化网格仍可能牵动附近背景
scene-motion.mjs 分画镜头、横卷推进、原作全幅适配 固定相机特写确认局部变化;不支持画后自由漫游
scene-stage.js 窟门构件错峰装配、夜灯与主动合成音境 昼夜、主动音频context实测;非历史音乐复原
experience.js 同一时钟驱动、迟到请求隔离、暂停/原作停帧、切画资源释放 两次暂停截图逐像素相同;一轮十画纹理回3,非长时无泄漏证明

Node9项、原图/HTTP完整性、逐画GPU、固定镜头人物实录、暂停、音境、原作和390px布局分别验证;物理手机、减少动态/失败/弱网分支与腾讯443尚未完成。数据见本地验收记录(未随公开源码分发)、本地验收记录(未随公开源码分发)、逐图依据、完整功能差距。原图未改动,前两版备份保留。

观看必须使用本地HTTP入口。直接打开index.html的file协议无法加载ES模块;新增明确提示与双击启动脚本,文件协议分支的浏览器检查被自动化安全策略禁止,未绕过、未宣称实测。

07-A / V0.2 历史基线:通用矿彩点云

本地历史运行截图不随公开源码再分发;本节是技术记录,不作为当前视觉验收。

以下为已备份V0.2历史基线,不是当前V0.3的默认效果:首页启动本地Three.js 0.186.0 WebGL2;从真实壁画取色生成浅层点云,叠加尘粒、GPU丝带、几何、镜头和反射。十画共用效果未满足用户逐图/人物动态要求,故本轮以上节方案重做;原图库和旧证据保留。

本地历史运行截图不随公开源码再分发;本节是技术记录,不作为当前视觉验收。

参考能力 敦煌独立实现 当前边界
真实GPU动态 采色点云、深度散开、相机、尘粒、丝带、反射 点云为艺术浅深度,不是文物测绘
叙事时钟 自动往返进度、手动seek、暂停/继续/重播 不是完整九色鹿剧情交互游戏
多画面资源 十画切换重采样、原图档案保留 不是十幅逐人物拆层骨骼动画
质量与回退 像素/粒子预算、离屏与隐藏停帧、减少动态默认暂停 390px仅浏览器视口,不冒充真手机
来源与权利 10份原图哈希、文件级许可、MIT依赖核验 8件长边2K+,2件待升级;无官方合作

新实现入口:experience.js,纯函数:motion-core.mjs,设计合同:DYNAMIC_DESIGN.md,实测:本地验收记录(未随公开源码分发)。上游根LICENSE不允许任意复制/修改/分发,敦煌项目未复制其业务源码、美术和音频;MIT只覆盖独立取得的Three与Reflector。

08 / 首批资源与后续门槛

首批十幅真实敦煌壁画联络表
经典题材策展精选,不是没有统计依据的“全网热度前十”。

原图/网页衍生分离,不AI补绘、不超分、不冒称原色。完整文件来源、窟号、年代、尺寸、许可主张与哈希见 RESOURCES.md 和 manifest。公开可看与正式商用授权是不同命题。

发布状态:本地候选、公开源码、云端上传和公网HTTPS验收分别记录,任何一项都不代表其余项完成。若进一步要求人物独立行走、完整舞蹈或真实持琴接触,应逐件制作合法的alpha母题层、锚点、补底和遮挡,不以本轮局部演绎冒充。

附录 A / 视觉渲染源码深审全文

以下保留完整原创技术解读。与总报告合读,视觉分工文末的“其他模块待审”已由附录B补齐;上游运行未知依然保留。

清明上河动态视觉链路深审与敦煌独立重建验收

审查日期:2026-10-23。固定版本:xianxie6/qingming-riverside@c575d242194fddafe33ec70dd01b860a75f09686。

本报告为原创技术解读,不复制上游长段实现。证据来自本地冻结源码静态逐行审查,未安装、构建或执行上游。源码存在、行为设计、实际GPU编译、设备运行和用户视觉接受是不同证据等级。这里不能把前两者写作后三者。

源码永久链接前缀:https://github.com/xianxie6/qingming-riverside/blob/c575d242194fddafe33ec70dd01b860a75f09686/。下文相对路径和行号均可直接拼接为该版本的 #L起-L止。

一、结论与边界

实际系统是三个连续阶段:真实程序化三维虹桥/船只 → 2.5D粒子绘画人物庭院 → Canvas2D可行走长卷(局部GPU水层)。不是十张图的相册,也不是完整三维汴京或全视角数字人。

  1. 虹桥、船、岸体具备真实世界坐标、透视投影、实体几何、相机路径、局部动态反射。
  2. 远岸主要是分深度布置的贴图平面;庭院是图片背景;粒子人物是从透明位图采色的浅浮雕,不是完整角色网格。
  3. 过场交互主要改变一个0–1叙事进度及小范围视差,不是第一人称自由行走。
  4. 主街市使用Canvas2D显示上下文。Three.js水层是离屏GPU画布再合成到世界坐标;因此独立重建不能只换皮CSS卡片,也不能虚称全场景3D。
  5. 代码/素材未获得一般复制修改再分发许可。独立敦煌项目可以重建上述抽象技术能力,但不得搬运上游代码、美术或音频。文物画面必须沿用独立核验的真实壁画来源及逐文件许可。

二、entry → input → state → camera → render → GPU → dispose

2.1 进入、预热、并发准备

src/crossing.js:3-19:warmCrossing()在pointerenter、pointerdown、focus时插入modulepreload与四张图片preload;尊重Save-Data,不在预热阶段创建WebGL或粒子。

src/crossing.js:21-45:点击后以active guard防重入,新建AbortController与原生dialog,按钮状态禁用,随后播放可关闭的音乐。file:协议分支提供本地服务器提示,不当作正常运行入口。

src/crossing.js:79–80,104–116:并行启动街市加载、目标落点准备,同时动态import createCrossing()。这里的“过场播放”与“后续可玩场景准备”相互重叠,减少场景切换空白。

依赖图:

crossing.js → crossing-audio.js(window.CrossingAudio)
            → dynamic-loader.js → scene.js/全局行走与人物子系统
            → crossing-three.js
                 ├─ crossing-motion.js / crossing-quality.js
                 ├─ crossing-world.js → crossing-details.js
                 │                      → window.ScrollFeatured / Inhabitants / ScrollMovement
                 ├─ crossing-water.js → water-three.js共享GLSL / window.ScrollWater
                 ├─ crossing-traces.js(Canvas2D投影标注)
                 └─ crossing-courtyard.js → crossing-hero.js

注意:src/crossing-tunnel.js虽然存在独立65°视角的环形隧道、线框和坐标精灵(1–51行),当前crossing-three.js没有导入它,当前发布白名单也不包含它。变量名tunnel在当前版本实际承载createCourtyard()返回值。不能把历史隧道效果写成当前有效链路。

2.2 输入不是散落动画,而是统一控制时间轴

src/crossing-three.js:76-96:

src/crossing-motion.js:16-25:createJourney()区分target/current/playing/held;seek暂停自动,auto以dt/50推进(全程设计约50秒),dt裁至0.08;current以指数追踪target,系数1-exp(-6dt),避免刷新率不同导致速度不同。

数学核心:平滑阶跃t²(3−2t),与指数衰减追踪,而不是CSS时间长度硬切换。装配progress按部件order错开,起点0.19×order,终点再加0.20(crossing-motion.js:2–4)。

2.3 状态机与后续场景交接

src/crossing-three.js:131-154:RAF dt裁0.06;页面hidden时不推进;庭院尚未准备时在0.68等候。未离场时target不超过0.95,progress≥0.948进入meeting并暂停;guide解除会面并继续到1,末端持续0.25秒后resolve。

src/crossing.js:47-65:会面界面是固定问答字典,并非LLM对话。Guide交给visual.guide,Alone直接enter。不得宣传为实时大模型人格或自主智能体。

src/crossing.js:81-99:enter等待后续场景prepared,提交阶段防重复关闭,调用AtlasTour.enterBridge(),成功后720ms淡出;失败显示重载和返回;prefers-reduced-motion直接进入可玩场景。

2.4 相机设计与三维边界

src/crossing-motion.js:5-14:初始横屏相机约[4.8,5.7,22],竖屏[4.5,7.8,46];过渡近点[0.5,2.15,10.2],末端[0,1.7,−8]。靠近窗口0.35–0.52、穿桥0.50–0.70;视线Z由0移至−20。船Z从7.8到−13,窗口0.42–0.72。

src/crossing-three.js:34–39,98–105:透视FOV44°、near0.12、far230,指数雾密度0.013,半球光/主光/补光。鼠标指数平滑1-exp(-3dt),横向最多约1.05、纵向0.5世界单位,在0.38–0.72渐隐视差。不是OrbitControls,不允许绕到平面后面。

三、程序化物体、二维角色变形、镜头跟随

3.1 虹桥真实构件而非把图片放大

src/crossing-world.js:36-99:倒角ExtrudeGeometry构件配合三批InstancedMesh;拱曲线是抛物线近似,高度由中心4.77左右衰减至两端。四道拱肋、45块桥面、两边栏杆逐件落位。每个部件记录目标位置/缩放/四元数/order/扰动,装配时以未到位比例叠加偏移,矩阵写入instance buffer。

src/crossing-details.js:4-9:部件到位后仍有弱呼吸(强度由未完成占比衰减),三轴不同频率的sin/cos和微roll避免生硬冻结。

src/crossing-world.js:68-81:边线利用instance matrix共享buffer生成线段批次,透明shader按距眼衰减;不是每根木头分别创建一套描边材质。markers取真实部件当前位置及arrive值(182行)。

src/crossing-traces.js:8-29:3D部件投影到Canvas2D叠层,裁去近远平面外/控件遮挡区,42×26间距抑制重叠,显示实际装配百分比。与庭院的装饰数字不同:crossing-courtyard.js:47–54数字是随time和索引生成的视觉标签,不能叫真实扫描精度/数据遥测。

3.2 船与船夫

src/crossing-world.js:117-150:船体截面沿Z采样、拼索引面;船篷以半圆截面和Tube骨架实现。具备真实空间体积,但后续材质大量换为从插画切取的墨色纹理(155–164),以统一艺术风格。

src/crossing-world.js:165–179,206–228:可用全局人物素材时,船夫由33列/49行基准采样并额外纳入握点行列构成二维可变形网格;帧上CPU更新顶点,人物面向相机。createRowingRig()先求手臂,再经rowingPoint()平滑蒙皮;桨沿上下握点方向延伸至指定水位,握柄Z凹入−0.026,避免桨穿出拳头。它不是标准骨骼glTF角色。

src/crossing-details.js:21-88:3.6秒划桨周期,手臂两段长度保持,利用movement.legJoints解肘关节;骨影响按距离四次衰减并连续肘混合,拳头刚体旋转;划水力度由周期0.08–0.52的半正弦决定,恢复段抬桨。

src/crossing-world.js:199-204:船随progress前进,同时独立以time轻微浮沉与摇摆;旗帜顶点以sin随时飘动。停止时间轴不必冻结所有环境微动,这是叙事进度与环境时钟分离的设计。

3.3 背景是舞台布景板

src/crossing-world.js:184-197:街景PlaneGeometry放在左右、近远不同深度,侧向不同旋转;片元以边缘smoothstep和颜色亮度阈值遮掉纸白。它提供有限镜头中的遮挡和视差,而不生成建筑背面、室内和自由行走空间。

四、GPU多pass、反射、纸感与庭院

src/crossing-three.js:14,28–38:renderer启用抗锯齿、高性能偏好,SRGB输出、ACES filmic、曝光1.10,PCF阴影且自动更新关闭。

src/crossing-three.js:45–70,107–126:

  1. 低分辨率半浮点反射target,镜像相机的Y映到2×waterLevel−eyeY,隐藏水面防自反射,使用斜近裁剪排除水下几何,每3帧更新。
  2. 阴影每6帧更新;三维世界画入paintedFrame,桌面2样本、移动0样本。
  3. 庭院单独画到自己的target,在0.685–0.765区间混合。
  4. fullscreen quad最终合成:四邻域颜色梯度生成暗边,强度0.21;从全景图底部细条采纸纤维,增量约0.025;庭院亮部9点加权采样形成微弱泛光,系数0.12。不是完整后期composer、不是物理曝光/真实纸张仿真。

src/crossing-courtyard.js:5–31,35–71:FOV39°,真实背景位图cover裁切;粒子主角、3.8×3.8地面透明接触影、350尘点、圆柱线框笼和6个数字精灵。主角形成窗口0.735–0.925;burst在0–0.8秒增强,在1.5–5.5秒消退;会面2.2秒后笼和标签淡出。鼠标视差只让水平角变±0.035弧度左右,竖屏相机距离14.5,横屏约10.5–11。

五、粒子画像如何形成和交互

src/crossing-hero.js:3-18:球形颗粒保留36三角形,合并接缝顶点后20顶点,减顶点shader执行数量。默认桌面80000实例、移动24000;不能只看“8万粒子”就理解为8万点绘制,它们实际是实例化低面球体。

src/crossing-hero.js:22-72:加载透明人物图、Canvas一次性getImageData,拒绝alpha<245像素;随机采样并保持像素颜色。人物高度映射为4.7世界单位,浅深度为低幅sin/cos加极小随机扰动(主幅0.10,次幅0.035),维持绘画面貌。每2048次检查CPU切片,超过8ms让出事件循环。

src/crossing-hero.js:31–51,74–79:实例粒子有scatter、phase、radius三个自定义attribute;聚拢smoothstep按phase错开,松散比例为未到位与burst的较大者;drift与vortex提供聚拢旋动。鼠标用世界坐标排斥核exp(−distance²/1.15),最大扰动系数约0.32;cursor指数追踪(系数5),hover指数追踪(系数3.2)。鞠躬只影响高度1.6–3.8以上区域、脚底不动,2.4秒半正弦。

因此对敦煌改造要先决定“全幅壁画粒子化”还是“经人工合法分层的人物粒子化”。直接拿全不透明矩形古画走此采样,只会形成矩形粒子平面;不能冒称壁画人物自动抠图、深度重建或可绕行数字人。原壁画不得为视觉效果默默篡改成伪复原。

六、街市水层与过场水层的真实算法

6.1 共享近似河面

src/water-three.js:7-52:岸边流速7世界像素/秒,河心以smoothstep升至22;3层噪声权重0.52/0.31/0.17。两份7秒周期错半相位的平移噪声交叉混合以避免不同深度流速撕裂;长亮缝另用11秒周期。波高是5个不同方向正弦叠加,频率k=0.05+0.026i,相位速度按sqrt(58k),再叠加平流细波。属于艺术近似,不是Navier–Stokes或实测水体模拟。

src/water-three.js:67-84:把screen UV反算世界画卷坐标,在河岸下16像素淡入;0.7世界像素差分估法线,偏折原底图采样约dx×16、dy×3.4,镜面幂40;超过画卷底部按fadeY淡出。水层不是渲染完整3D河床,是对原画水区重采样及着色。

6.2 水磨瀑布

src/water-three.js:85-122:单独pass用自由落体时间反解tau=(sqrt(v0²+2gy)−v0)/g,g=185、初速35;以tau−time平移噪声使条纹向下加速。下部水幕变宽、边缘破碎、孔洞、飞溅及冲击泡沫/环/薄雾由噪声和距离场组合。参数是绘画像素尺度,不是米制真实物理数值。

6.3 传输与合成优化

src/water-three.js:131-199:透明、无抗锯齿、预乘alpha renderer;像素比不超过1.35。仅裁河岸以下的底图并多留20世界单位边距,纹理无mipmap、线性过滤,backdropKey改变才上传;scissor在片元shader前限制水面/瀑布区域,最后drawImage回Canvas2D世界坐标。上下文丢失置active=false、恢复清缓存,但此类没有公开dispose方法,独立重建应补齐生命周期。

src/crossing-water.js:59-77:过场河面是240×240三维平面,水位0.015,载入夏季河水纹理;最多12条环形水波事件的循环buffer,桨力越过0.16发一圈,船速0.1–8且间隔>0.32秒发尾流。波寿命3.8秒,三环半径每秒增0.34,透明度平方衰减;反射强度用视角近似Fresnel从0.025到0.08,而非完整物理材质。

6.4 关键静态缺陷:过场共享shader不自洽

高可信静态缺陷,运行影响未实测。src/crossing-water.js:13插入ThreeWaterRenderer.riverSurfaceShader,而该字符串的ripples/seams/heightAt引用noise()与bankAt();这些函数只定义在water-three.js的另一个完整fragmentShader里(59–64行),不包含在被导出的字符串内。过场自身fragmentShader未补定义。

另外crossing-water.js:29用3实参调用shadeRiver(base,spec,h),但共享定义在water-three.js:45需要第4形参streak。静态上应出现未声明函数/参数签名不匹配的GLSL编译错误。Three.js着色器错误未必作为可捕获JS异常传播,所以crossing.js的try/catch不能被当作这类错误的有效fallback证明。

独立重建必须使用自包含GLSL模块、明确所有函数/统一变量依赖,在真实GPU上下文调用shader/program编译状态并收集错误,且验证最终像素,不得仅靠JS语法检查或静态字符串测试放行。

七、性能预算、释放、构建裁剪

src/crossing-quality.js:2-21:宽度<600认为mobile,核数≤4视limited;像素预算分别80万/140万。ratio=min(DPR、移动1/桌面1.25、sqrt(预算/面积));反射256/512、阴影512/1024。慢帧统计至少2秒且30帧,平均帧耗>26ms才将ratio×0.82,忽略dt>0.15的后台暂停。不自动升回;这只是降级策略,不能保证任何设备60FPS。

src/crossing-three.js:15-26:keep登记GPU资源,dispose幂等、取消RAF、AbortController解绑输入、resolve等待者、dispose各资源、移除2D痕迹画布、释放renderer、forceContextLoss并删DOM。异步迟到资源在keep中立即dispose。缺点是资源请求/人物CPU采样本身未收到独立AbortSignal,取消不保证网络下载和长任务立刻停止。

src/crossing.js:66-78:关闭dialog同时abort、音乐dispose、视觉dispose、恢复焦点与入口状态。音乐有revision防止旧play Promise回调覆盖新状态(crossing-audio.js:20–40)。

scripts/crossing-release.mjs:3–25,33–60:白名单包含当前crossing-courtyard/hero/details/water,不含历史crossing-tunnel。构建删除explore、餐馆、中秋入口与节庆代码/音频引用,保留后续四季街市。部分PNG是兼容老页面URL而保留,不能把仓库文件总量当首屏下载量。

八、敦煌独立重建的最低能力合同

以下是建议实现与验收,不是上游已证实结果。满足它们后才可称“借鉴完整动态技术体系的独立敦煌项目”。

环节 独立敦煌实现 必须提供的验收证据
入场 原画—窟门/藻井/回廊程序几何展开,滚动/拖动/自动统一时间轴 0/25/50/75/100%状态截图、连续正常速度录屏
真实空间 透视相机、近远遮挡、至少一组有厚度可观察的程序化几何;原壁画作有来源的画面层 相机矩阵/位置变化,轮廓和遮挡跨帧改变,不是图像scale
相机 横竖屏不同构图,限制在真实画面可支持视差范围 桌面/手机宽高比录屏,边缘无露底拉伸
粒子 从合法壁画采色,GPU实例/点绘制、渐进重聚、可打散、鼠标排斥 粒子实例/点数、draw-call统计、至少聚合与分散两种真实截图
文物保真 默认可返回不变形原作;衍生动画明确标识;不虚称复原 原画比较/来源、改动说明与窟号核验
时间/输入 seek、暂停、继续、重播、键盘、拖动均对同一状态生效 反向seek/端点/连点/切tab压力交互实测
场景交接 资源未好等候,成功后进入真正可交互场景,不以打开图库代替 慢网、失败、重试及完成主链路录屏
GPU特效 与敦煌主题相符的尘粒/壁画色层/浅浮雕光感;不必强搬河水 shader compile/link状态、控制台零图形错误、实际可见像素
自适应 DPR/像素数/粒子预算限制,持续慢帧后降级 resize日志、降级前后ratio/FPS采样,设备型号与采样时长
无障碍 减少动态、静音、跳过、键盘、焦点恢复,静态fallback保留内容 系统reduce-motion与WebGL不可用真实分支
生命周期 每次进入/退出均解绑/释放,不遗留多个RAF/WebGL canvas/音频 10次开关后canvas数、活动loop/监听计数、GPU资源趋势
资源/许可 原图自包含、逐文件源/尺寸/hash/许可/署名与衍生改动 白名单、无失效请求,许可证清单与独立实现声明
发布 仅本地预览候选,通过后再按授权部署 构建测试与浏览器实测分别列出;不擅自发布

不能将“十张高清壁画已下载”“页面可打开”“测试断言通过”分别升级成“完整动态逆向”“真实GPU已正常”“用户已验收”。完整源码分析还需要主交互/人物/天气/寻物等其他链路的独立审查,本报告仅覆盖指定视觉子系统。

九、定位速查

此前报告请求核对的七个相对路径均准确存在:src/scene.js、src/crossing-three.js、src/crossing-world.js、src/crossing-hero.js、src/movement.js、src/dynamic-loader.js、src/crossing-quality.js。

附录 B / 内容系统与逐模块职责全文

清明上河:街市、角色、内容系统与交付链源码审查

审查对象:xianxie6/qingming-riverside,固定提交 c575d242194fddafe33ec70dd01b860a75f09686。审查日期:2026-10-23。本文为原创技术归纳,不附上游长段源码,不执行上游程序。

1. 覆盖声明:不要把扫描说成运行

2. 结论与正确技术定性

项目不是“所有建筑与人物都做成完整3D模型”。默认街市可游玩段使用 Canvas2D 做最终显示,内部复用一个原生 WebGL 人物网格面与一个 Three.js 水层;穿越段另外创建真实Three.js场景。视觉成功主要来自手工校准的独立绘画层、稳定脚底/手部锚点、时间驱动的局部动作、精确遮挡与镜头调度,而不是给整张图一个CSS悬浮动画。

证据:scene.js:9-28 初始化2D显示与角色画布;inhabitants.js:6-22 创建独立WebGL PeopleMesh;scene.js:856-945 合成多层;scene.js:1021-1065 每帧更新。技术上应称“混合2D/2.5D街市 + 独立3D穿越”,不能一概叫全3D世界。

3. 从入口到像素的真实链路

index.html
  ├─ atlas.js:全景图 + 热点 + hash 路由 + 隔离非活动页面
  ├─ dynamic-loader.js:19个经典脚本并发请求、按插入顺序执行
  │     └─ scene.js(type=module)
  │           ├─ world / movement / population / street-life:世界与行为
  │           ├─ Inhabitants + Featured + Workshop:人物切片、变形、动作
  │           ├─ Districts + BackdropCache:建筑图层与可见区域资源
  │           ├─ Nightfall / RainEvent / Seasons:环境状态
  │           ├─ ThreeWaterRenderer:水面特殊层
  │           └─ requestAnimationFrame → update → render → 2D最终画面
  └─ crossing.js:3D穿越对话与镜头;结束后调用 AtlasTour.enterBridge()

3.1 全景与街市不是同一张图简单放大

atlas.js:3-10 全景坐标2172×724,4个热点映射不同 world 位置(-1550/650/1560/3360)。launchScene(88-116)先 loadQingmingScene,再等待选中街区资源 prepareQingmingEntry,派发 atlas-enter 后才隐藏全景。scene.js:1209-1228 同时搬移玩家和镜头,并清理旧乘船状态。isolate(atlas:83)给非当前页面元素设 inert,避免隐藏控件仍参与交互。

3.2 启动与可见资源优先

dynamic-loader.js:3-9 列19个依赖,add(24-29)设置 async=false,Promise.all(39)使请求同时发出、脚本仍按插入顺序执行。准备阶段通过 image preload 与 modulepreload 预热(13-21)。街市的“脚本加载成功”和“素材可用”分开:等待 atlas-ready / atlas-error,30秒超时,并防止失败ES模块被重复插入后永久等待(40-54)。页面load后低优先级预载受 file: 与 Save-Data限制(57-65)。

districts.js:8-32 根据视区只加载西/东必要画片,使用pending Map去重、20秒超时,可重试;选中场景画完后再低优先加载其余地区(scene:1229-1235)。render 遇未加载建筑保留最后完整帧,不在空背景上画人物(scene:863-873)。

4. 状态、时间与画面合成

4.1 三套状态不能混淆

frame 将 dt 限制至0.05秒(1022),背景tab/全景/节庆弹窗/加载范围时跳过街市模拟(1023)。uiTime可用于短时交互水纹,time只在running时增长(1034);人物、桥故事与雨事件收到运行开关对应dt。镜头以指数响应追目标,不再依赖某个固定刷新率(1051);接近物理像素百分之一后直接归位,避免静止时持续作废背景缓存(1052-1054)。

4.2 画面顺序本身就是核心算法

scene.js:856-945 真实渲染顺序:建筑缓存 → 湿地 → GPU水面或2D水纹 → 建筑夜光/天空 → 动态透明前景 → 过桥船 → 居民/桌椅遮挡/路人/水车/点击水纹 → 瀑布局部特效 → 渡船及乘客舷边遮挡 → 按水线排列的环境船 → 雨棚/风动小物/蒸汽/雨雪 → 前景夜色source-atop → 最终灯饰。

单纯将整张壁画UV扭动,不能复现这里的“人物在桌后、行人在桌前、船客在舷边后、水车遮路人”的效果。每个可动目标必须有独立贴图/遮罩/锚点或可信的局部图层重建。

BackdropCache.get(scene-backdrop:6-18)按视区宽高、密度和district revision缓存世界空间画片,并在两侧保留不超过160单位余量。镜头小幅移动仍采同一个缓存,不每帧重画整街;季节切换显式invalidate(scene:103)。

5. NPC与人物:不是实时AI代理

5.1 位置与行为是作者数据和确定性状态机

population.js:7 定义世界范围[-2172,4344],跨度6516、高724。居民数据32-65、步行路线67-72、职业映射74-86。成年人统一61–66单位,孩童与坐姿另设高度带(8-22)。scene.js:791 统计是居民+40个walker+5个legacy行人+1主角;不要将其他探索模块的320人直接算到该街市。

street-life.js:10-16 六个重复编排事件:茶铺、菜市、陶坊、布铺、儿童、货运。storyAt(33-87)按time取阶段、actor pose和prop owner;journey/itinerary(18-31)使用平滑区间保持动线连续。搬货被玩家上船打断时,挑夫从真实位置回码头而不是瞬移(127-142)。Director.advance(148-155)对每个walker维护独立clock:迎面避让/桥阻塞时速度率衰减为0,恢复后继续同一相位。

这是“编排式行为系统”,不是行为树+大模型对话,更非每个NPC独立推理。对本分工审查入口、前端主路径与Worker的限定搜索,没有发现为这些行为发起LLM请求;此结论不覆盖仓库外服务。

5.2 真正的局部动态来自约束网格

movement.stepWalk(29-44)将目标速度指数平滑,并精确积分,避免30/60/120Hz走出不同距离;短按目的地以press位置记账(12-27),非keyup临时补步。

gaitAt(48-60)用已走距离而非纯墙钟驱动步态;支撑期脚底落地、摆动期抬脚,至少一足支撑;legJoints(63-74)是二维两骨IK,坡地够不着时大腿小腿同步伸长。deform(162-200)按蒙皮区域施加躯干、点头、手部与脚部影响;长袍单独处理,不把下摆拆成两条裤腿。

inhabitants.prepareFrames(107-130)从图集裁人物,基于边缘flood-fill去纸底;不能一刀去白,否则白袖、瓷器等也会透明。paperSteps(153-177)仅连通外部纸色,边缘再反白污染。footContacts在alpha>96的脚底测接触点(movement:151-160)。衣服按上/下衣掩膜着色,头脸等受保护(inhabitants:192-214)。

sprite(350-469)把人物分成躯干/袍/独立腿面片,调用movement.deform产生网格顶点。动态绘制两条路:WebGL PeopleMesh把顶点与UV上传为三角形(6-69),或Canvas逐单元仿射采样(487-521)。走路人物每帧更新;普通居民约12Hz缓存动作画片,近看陶工更高频(388-403)。WebGL纹理Map至多128项,静态纹理只首次上传;顶点buffer复用bufferSubData(47-68)。这不是完整3D骨骼角色,但比整张sprite平移复杂得多。

Inhabitants.draw(291-349)按可见范围裁剪,居民 → 家具 → 路人排序,批次绘图保留独立合成区域;点击命中可添加4秒关注,不篡改原故事动线(290-295、299-318)。Featured.Characters(21-59)同样去底并测接触点,画师/船夫的抓握点从原图归一化换算,船桨由双手决定(15-19)。

6. 船、桥与交互因果

world.js:23-41 以手描桥面和台基路径求streetY,使用单调Hermite式切线限制避免折点。createFerry/stepFerry(60-96)明确等待→靠近→停泊→离开→返回;乘客额外boarding→sailing→disembarking→moored,航程48秒、上下船各3.4秒。passengerPose(116-124)沿连接岸与甲板的多段路径,不瞬间贴到船上。环境船同速等距循环避免互相追尾(49-55)。

bridge-event.js:9-38 虹桥剧情是idle→approach→call→rig→guide→clear→record→complete。牵引输入先以tension低通过滤,最佳力约0.56;过力>0.85增加overpull且减速0.006,船工仍保有最低推进、不会卡死。参与结果由累计work决定(16、24-35)。vessel(41-55)用缩放、轴向和位置曲线表现远近,不是刚体流体模拟。residents(57-64)将桥上目光/拉绳动作覆盖到已有居民。

UI在 scene.js:1067-1206 将拖拽、双指缩放、双击、滚轮、方向键、E、Space、Esc、牵绳滑块、声音与全屏映射到同一状态,失焦/visibilitychange清除held输入(1180-1182),避免回到页面还在持续走。可访问名称/slider值/状态播报均在HTML和DOM更新中存在,但不是本次无障碍实测合格证明。

7. 环境、四季与声音

8. 默认交付物与仓库实验场必须分开

scripts/build-static.mjs导出的API默认profile='all'(8),但CLI缺省profile='crossing'(50-52);npm run build调用CLI,所以正常构建是crossing精简版,npm run build:all才全量。不能只看导出函数缺省值误判线上发布。

crossing-release.mjs:3-25白名单包括穿越+街市+四季+水面和对应资源;crossingSource(33-60)变换入口移除explore链接、孙羊店入口、中秋dialog及脚本/样式,scene的festival import替换为空钩子,店家图加载删除,中秋音频地址改为日间。源仓库仍保留这些模块,并不表示默认dist包含它们。

index.html:18中秋data开关本身false;festival-street.js:3遇false直接return;烟花脚本未被入口引用、index:114明确停用。古城探索另有自己的explore.html、CSS/DOM人口和收集系统;扩展街区另有extension-preview入口生成脚本,默认构建没收这些模块。

构建先验证白名单路径与存在性、再只允许替换根下dist(build-static:17-40)。check-public-assets(36-55)递归检查相对URL和排除private/build-only文件;其正则/模板检查不能证明运行时条件路径100%可达或视觉正确。Three.js vendor只经esbuild minify,业务JS仍独立文件非一个框架应用bundle(29-35)。

package.json仅声明devDependencies esbuild 0.28.1、wrangler ^4.134.0与Node>=22;Three.js以vendor模块提供,不能据package.json硬猜其版本。没有React/Vue/数据库支撑人物世界的证据。

GitHub工作流 .github/workflows/verify-and-deploy.yml:13-44 是npm ci→npm test→npm run build→Wrangler dry-run→上传dist→Pages部署,只有master非PR事件触发部署。scripts/deploy-pages.mjs:13-18另设仓库远端/精简profile校验,通过临时gh-pages工作区把dist提交并workflow dispatch(65-70)。这是上游作者部署脚本,不应在本项目直接运行,它会推上游仓库。

9. 后端并不驱动动画

worker.js:4-20唯一业务路由 /api/visits 接受POST,D1 UPSERT返回累积count,其他请求直接ASSETS.fetch。CORS只对作者GitHub Pages origin返回头,失败503、不缓存。visits.js:6-14在本机直接不统计,线上按host选择Worker endpoint、3秒abort;失败只影响计数,不影响人物。此counter为请求次数,并非经过反作弊或独立访客去重的UV。

10. 测试证据如何正确解读

45个测试文件存在,但本次未执行。代表性映射:

测试文件 编写的检查 证据类型与局限
world / walking / movement 渡船上下船、刷新率等距、脚底连续与两骨约束 纯函数数值测试;可查算法边界,不等于真实画片无穿帮
street-life / bridge-event / weather / night 阶段有序、pause不推进、避让连续、过力可完成、伞和夜间人群 确定性模拟;不证明主循环所有接线和输入都正确
loading / districts-loading 并发启动、promise去重、错误重试、只拉可见街区 VM+假的DOM/Image/event;不是真网速/浏览器请求瀑布
rendering 衣服/腿网格/缓存/alpha去底、GPU atlas复用 代理Canvas/WebGL、记录调用;GLSL并非由真实GPU编译,不能据此宣称实际纹理上传耗时已测
performance 分数DPR时画布不重复resize、孙羊guest复用backing store 计数桩检查(tests/performance:6-41);不是FPS benchmark
scene-backdrop / water-upload 缓存复用、source变动才needsUpdate、局部水区上传 纹理对象桩与调用次数,不是真显存或GPU时序
entry / bridge-railing / water 抽取源码片段执行或正则断言接线存在 结构回归对重构格式敏感;不等于真实鼠标/键盘路径端到端通过
publishing 临时fixtures检查资源路径、private不进dist、crossing裁剪 确有构建函数调用,但大量资产用'asset fixture'替代(publishing:55-58),不证明真实图音频可解码
explore / collection / city-fusion / extension-* 人口/遮挡/收集幂等、花店状态、步态/图集锚点 覆盖非默认模块;即使通过也不能把它当默认线上已启用

本分工对45个tests做了名称/正文模式检索,在已查测试中没有发现Playwright/Puppeteer/Chromium真浏览器驱动;不据此断言仓库外不存在手工验证。docs性能记录是作者记录,既非本次测量,也不能替代当下同设备线上数据。

11. 每个非穿越src模块职责简表

说明:D=主路径深读;S=正文/导入导出/代表调用扫描;G=生成数据/坐标结构扫描未逐点核验。water-three与12个crossing相关模块交由另份报告,本表列其余70个模块。

文件(均在src/) 职责 审查层/默认crossing包
atlas.js 全景热点、hash、街市入口与可访问隔离 D/是
atlas-atmosphere.js 北京时间、月相/天气相关首页氛围 S/否
atlas-festival.js 配准于全景的节庆天空装饰 S/否
atlas-firework-shapes.js 生成灯笼等烟花点阵 G/否
atlas-fireworks.js 烟花粒子、尾迹、表演与首页UI S/否
boat-song.js 与歌女动作同步的拨弦/元音声学合成 S/否
bridge-art.js 虹桥船只投影、桅杆/绳索/桥前景 S/是
bridge-event.js 过桥阶段机、拉力、进度和结果 D/是
bridge-railing.js 桥栏遮挡路径和原画恢复 S/是
city-fusion-data.js 城市人物配准/尺寸修订数据 G/否
city-fusion.js 修订融合、景深排序、遮挡与家具 S/否
city-point-fixes.js 城市人物个别手工位置修补 G/否
collection-data.js 25目标、分组、碰撞/遮挡与存档清洗 S/否
collection.js 收集UI、alpha命中、提示、进度持久化 S/否
districts.js 西/中/东图加载、拼接、家具/建筑遮挡、水车 D/是
dynamic-loader.js 并发有序脚本、预热与ready/error屏障 D/是
explore-atmosphere.js 城市探索的世界坐标环境DOM动效 S/否
explore-data.js 旧探索目标/彩蛋/交互内容表 G/否
explore-geometry.js 矩形/多边形命中、最小面积目标、存档清洗 S/否
explore-people.js V3人口DOM图集、LOD、镜头和收集入口 S/否
explore-population.js 地区/职业定义与320绘制成员组装 S/否
explore.js 旧12目标探索、拖拽缩放、提示/存档/音色 S/否
extension-flower-customers.js 花店顾客进出门和店员服务姿态 S/否
extension-flower-shop.js 买花/插瓶/旋转/近看dialog S/否
extension-flower-state.js 试用币、库存、花瓶槽位、存档净化 S/否
extension-flower-street.js 花街局部角色精修与独立走行路线 S/否
extension-limited-animation.js 逐绘关键帧图集、脚底/头部校准与距离驱动walk S/否
extension-motion.js 按职业动作周期、角色动作计划与街声 S/否
extension-people-data.js 扩展街区人物/道路/atlas元数据 G/否
extension-people-layout.js 显示比例、花店顾客角色拆分和位置修订 S/否
extension-people.js 裁alpha图集、动作计划、puppet/limited渲染选择 S/否
extension-preview.js 七画片长街、仓场/客栈交互、河船、性能调度 S/否
extension-puppet.js 二维变形三角网格帧缓存,96MiB预算 S/否
extension-walkers.js 连续路段、启停行走计划、步长与距离相位 S/否
extension-workshop-state.js 起吊/卸包/搬运/回位、门帘、顾客/店员阶段机 S/否
extension-workshop.js 道具资源、花肆门帘遮挡、仓场actor合成 S/否
featured-characters.js 画师/船夫去底、双手锚点、脚底及boat尺度 D/是
festival-lighting.js 节庆背景、月亮和灯光层 S/否
festival-street.js 中秋独立街景及演员控制(入口开关false) S/否
firework-audio.js 烟花录音buffer、背景loop与静音生命周期 S/否
inhabitants.js 人群裁图、着色、GPU/Canvas蒙皮、批绘、命中 D/是
midautumn.js 东街节庆门/灯笼和双pass灯光钩子 S/否(发布替换为空钩子)
mill-wheel.js 从原画抽水轮、透视纹理重建与转动 S/是
movement.js 输入积分、步态、职业姿态、IK与蒙皮变形 D/是
night.js 昼夜渐变、窗灯、月星、人群退场、氛围合成 D/是
people-frames.js 人物图集裁框生成表 G/是
people-masks.js 人物遮罩坐标 G/是
population-v3-data.js 唯一人物资产、可行走面与落脚修订 G/否
population.js 街市居民/行人/职业/身高数据和居民姿态 D/是
river-boats.js 扩展街区撑船角色分层、船行与歌女动作 S/否
scene-backdrop.js 有余量的世界空间建筑缓存 D/是
scene.js 主状态、输入、仿真循环、资源与最终合成 D/是
seasons.js 异步季节控制器、服装/气候/落叶雪 D/是
sound.js 录音与WebAudio事件声、空间声像和雨声ducking D/是
street-details.js 故事道具绘制、交接物与风动细节 S/是
street-life.js 六故事编排、避让clock、渡船货运协调 D/是
sunyang-actor.js 店内画师Canvas人物与路径 S/否
sunyang-guests.js 食客Canvas、落座和桌面菜肴布置 S/否
sunyang-host.js 独立alpha店员、动作锚定 S/否
sunyang-sound.js 店内音乐/拨弦点击、用户手势解锁 S/否
sunyang.js 入店→选座→点餐→上菜流程与场景镜头 S/否
tea-study-actors.js 茶摊局部对比的原角色图集/坐标 S/否
tea-study.js 修改前/后/左右对比、拖拽缩放与载入失败恢复 S/否
visitors-data.js 独立城市游客与尺寸修订数据 G/否
visits.js 仅线上请求访问计数、3秒timeout D/是
wardrobe.js 服装多边形、受保护区域、配色与季节工装 S/是
water.js Canvas回退水面线条与扰动函数 S/是
weather.js 雨阶段、伞、湿地/雨棚/雨线 D/是
workshop-actors.js 季节作坊人物贴图裁切与抓握道具 S/是
world.js 桥/台基路径、渡船阶段、乘客路径和环境行人 D/是

12. 敦煌独立重建应该迁移什么

可复用的是方法,不是受限源文件或上游插画:

  1. 将“真壁画存档”与“动态艺术演绎”明确分层;原图只读保留,动态输出标注非文物复原。
  2. 每个被宣称“人物在动”的母题有自己的alpha层、关节/手指/飘带根部锚点、适当修补底板与遮挡。没有分层就不承诺原画人物完整动作。
  3. 大面积色层以浅深度/镜头视差处理;局部飘带/云气用二维网格或Shader,法器、手、头面保持不同权重,避免整身橡皮抖动。
  4. 统一scene clock;用户暂停时人物/尘粒/纹理动画全部停止。镜头用独立状态,滚动推进可逆且不能绑死自动播放。
  5. 真正的WebGL效果要有frame计数、可见像素变化、上下文丢失回退及一次真实浏览器录屏证据。不能用“script存在/测试通过/有Canvas标签”替代效果在动。
  6. 保留静态考据模式并不等于默认动态做完;首页必须直接看到可解释、可暂停的动态舞台,再进入高清资料库。

13. 权利与剩余未知

LICENSE:3-9明示公开查阅不授予复制/修改/分发/商用额外许可,因此独立重建不复制业务源码/画片。docs/ASSET-INVENTORY.md:7-10说明插画imagegen制作、音频来源授权不完整,Three.js MIT与字体OFL仅约束对应第三方组件。技术分析与商业素材复用是两件事。

待补:主审的crossing/Three水GLSL深审;实际部署dist与固定提交的一致性;真实GPU截图/录屏、低端移动机、音频实际播放及设备热衰减;大数据坐标/每个素材授权;上游全部测试实跑。未有证据前不将这些状态写为“完整验证完成”。