DarthSoluke commited on
Commit
b0b604c
·
verified ·
1 Parent(s): aedecda

Document all EgoRenderer versions and audited GRAB rendering campaigns

Browse files
README.md CHANGED
@@ -28,6 +28,7 @@ pinned: false
28
  | 样例 | `#samples` |
29
  | EgoRenderer | `#synthetic/progress` |
30
  | 合成版本、读取、样例 | `#synthetic/versions`、`#synthetic/reading`、`#synthetic/samples` |
 
31
 
32
  筛选条件保存在URL中,例如`#catalog?source=egoexo&method=marker`。
33
  原有`#ds-<id>`及全部合成页地址继续可用。
@@ -44,11 +45,13 @@ pinned: false
44
  | `src/preview.js` | 同帧预览、标注切换、缩放、视频、出处 |
45
  | `src/reference.js` | 标注方法、转换路线、素材覆盖 |
46
  | `src/synthetic.js` | 只读合成进度、版本和读取文档 |
 
47
  | `src/ui.js` | 转义、图标、表格及共用界面 |
48
  | `src/styles.css`、`src/synthetic.css` | 全站样式及生产页局部样式 |
49
 
50
  ```bash
51
  python3 tools/build.py
 
52
  node --test tools/frontend.test.mjs
53
  python3 -m http.server 8767 --bind 127.0.0.1
54
  ```
@@ -63,6 +66,8 @@ python3 -m http.server 8767 --bind 127.0.0.1
63
  - `data/preview_pool.json`、`data/sampling.json`:素材池与抽样记录。
64
  - `data/figures.json`、`data/videos.json`:官方图与连续序列来源。
65
  - `data/egorender.json`、`data/egorender-registry.json`:合成数据语义与执行登记。
 
 
66
  - `downloads/egorender_reader.py`:NumPy逐帧读取器。
67
 
68
  预测标注、辅助拟合、生成完成与训练资格分别记录。原始MANO驱动合成渲染,
@@ -78,9 +83,17 @@ native_object_poses.npz;下半身为生成结果,明确标为非原始GT。
78
  公开快照来自`DarthSoluke/EgoRendererStatus/status.json`,60秒刷新,超过180秒标为过期。
79
  页面保留最近一次成功快照,不把网络失败当成进度归零。执行修订不等于数据发布版本。
80
 
81
- 状态发布器保留在内部工作区,复用原有SSH master;HF凭据不进入浏览器或PRO。
82
- 连接丢失后,发布器在本机互斥锁下重建同一个配置的master;存在匹配的活进程或
83
- 残留socket时不另开连接、不删除socket。发布器保持原有限截止时间,可用`--until`
84
- 指定恢复时不得延长的截止时间;不建立cron或新的聊天定时任务。
85
- 公开Space仅包含静态页面、脱敏摘要、样例与读取器,没有生产控制API。
86
- 维护者本机睡眠或发布器结束会导致公开进度过期,不代表远端生产已经停止。
 
 
 
 
 
 
 
 
 
28
  | 样例 | `#samples` |
29
  | EgoRenderer | `#synthetic/progress` |
30
  | 合成版本、读取、样例 | `#synthetic/versions`、`#synthetic/reading`、`#synthetic/samples` |
31
+ | 单版本详细说明 | `#synthetic/versions/001` 至 `#synthetic/versions/006` |
32
 
33
  筛选条件保存在URL中,例如`#catalog?source=egoexo&method=marker`。
34
  原有`#ds-<id>`及全部合成页地址继续可用。
 
45
  | `src/preview.js` | 同帧预览、标注切换、缩放、视频、出处 |
46
  | `src/reference.js` | 标注方法、转换路线、素材覆盖 |
47
  | `src/synthetic.js` | 只读合成进度、版本和读取文档 |
48
+ | `src/versions.js` | 六版本对照、详细参数、历史渲染批次和证据边界 |
49
  | `src/ui.js` | 转义、图标、表格及共用界面 |
50
  | `src/styles.css`、`src/synthetic.css` | 全站样式及生产页局部样式 |
51
 
52
  ```bash
53
  python3 tools/build.py
54
+ python3 tools/build_versions.py
55
  node --test tools/frontend.test.mjs
56
  python3 -m http.server 8767 --bind 127.0.0.1
57
  ```
 
66
  - `data/preview_pool.json`、`data/sampling.json`:素材池与抽样记录。
67
  - `data/figures.json`、`data/videos.json`:官方图与连续序列来源。
68
  - `data/egorender.json`、`data/egorender-registry.json`:合成数据语义与执行登记。
69
+ - `data/egorender-versions.json`:V001–V006详细方法、参数、覆盖、格式和限制。
70
+ - `downloads/egorender_versions.md`:从同一份结构化版本资料生成的可下载参考,附证据SHA索引。
71
  - `downloads/egorender_reader.py`:NumPy逐帧读取器。
72
 
73
  预测标注、辅助拟合、生成完成与训练资格分别记录。原始MANO驱动合成渲染,
 
83
  公开快照来自`DarthSoluke/EgoRendererStatus/status.json`,60秒刷新,超过180秒标为过期。
84
  页面保留最近一次成功快照,不把网络失败当成进度归零。执行修订不等于数据发布版本。
85
 
86
+ 状态发布已迁至PRO独立监督进程;专用凭据只允许更新状态仓库,保存在私有控制目录。
87
+ 浏览器和公开Space不含凭据、内部传输脚本或生产控制API;本机Codex退出不再是
88
+ 发布前提。网络失败时保留最后快照并显示过期,不把生产进度归零。
89
+
90
+ ## 版本资料(2026-11-03)
91
+
92
+ 六个数据/方法版本、四个GRAB渲染批次及V006执行修订分别展示,不能按数字混为
93
+ 同一发布序列。V005的30动作名称、203物体/动作组合、1,314原始录制及2,425视频
94
+ 分别计数;四批次全部渲染设置、相机、RGB效果、场景、文件布局与重叠关系有独立表。
95
+ V002/V003为有限试验,不称全量数据;V006只使用原生手驱动渲染并保留成对压缩深度。
96
+
97
+ 本次仅发布版本文档和前端。数据集目录、预览来源、读取器、登记簿及进度快照保持
98
+ 原字节,不启动生产/回填/上传任务。通过`tools/deploy_version_history.py`按审阅基线
99
+ 和当前远端parent提交;遇到并发修改停止,不覆盖其他维护者的变更。
data/egorender-versions.json ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema": "egorenderer.public_version_history.v1",
3
+ "updated": "2026-11-03",
4
+ "naming": [
5
+ ["数据与方法版本", "V001–V006", "拟合、深度试验与交付合同的演进;不表示每个版本都重新渲染了一套RGB。"],
6
+ ["渲染批次", "grab_recipe_production_v4 / grab_seeded_remaining_production_v6", "历史任务名。两者都出现在HF Ver.005里,名称中的v6不等于数据发布V006。"],
7
+ ["执行修订", "279 / 299 / 351 / 356", "资产修复、GPU匹配、调度或打包实现;当前所属数据版本仍是V006。"]
8
+ ],
9
+ "comparison": [
10
+ ["001", "标准MANO参数拟合", "原渲染不变", "不新增深度", "序列共享形状、逐帧姿态;辅助拟合不是原始GT。"],
11
+ ["002", "主动双目深度试验", "复用已完成RGB", "散斑投影+8路径SGM", "2条GRAB动作、各3帧的有限试验。"],
12
+ ["003", "稀疏锚点深度试验", "复用试验RGB", "稀疏GT锚点+RGB/XY插值", "非双目、非PromptDA模型推理、非当前生产深度。"],
13
+ ["004", "左手形状基底修正", "原渲染不变", "沿用原深度", "1条动作275帧;右手复用V001。"],
14
+ ["005", "GRAB完整参数更新", "保留各历史批次RGB", "历史逆camera-Z", "1,314原始序列,2,425个渲染视频;只更新拟合附件。"],
15
+ ["006", "原生手强随机化合成", "原生几何驱动新合成", "压缩GT+主动双目噪声深度", "ARCTIC、OakInk2分开;每源1次生产,辅助拟合不驱动像素。"]
16
+ ],
17
+ "versions": [
18
+ {
19
+ "id": "001",
20
+ "delta": "把个体化GRAB手表面映射到标准MANO参数空间,固定方法和产物命名;不改变渲染所用的原始手表面。",
21
+ "groups": [
22
+ {
23
+ "title": "拟合合同",
24
+ "headers": ["项目", "具体设置"],
25
+ "rows": [
26
+ ["目标", "原个体化MANO在原始姿态和translation下的778个对应顶点;左右手分别求解。"],
27
+ ["优化变量", "每手每序列共享beta10;每帧pose48=global rotation3+finger pose45,轴角弧度,非PCA,flat_hand_mean=true。"],
28
+ ["固定量", "原逐帧translation、对应顶点索引和已明确交付的source_frame_indices;不额外抽帧。"],
29
+ ["损失", "所有交付帧、所有778顶点等权平均平方欧氏距离;坐标为毫米,损失单位mm²。"],
30
+ ["不使用", "joint loss、beta/pose prior、时序平滑、腕部居中、额外腕部平移、强制腕部旋转对齐或姿态角上界。"],
31
+ ["初始化", "零姿态非居中表面形状估计+原始完整pose;已有序列估计可继续,不重启已完成优化。"],
32
+ ["求解器", "float64 L-BFGS,strong_wolfe;history50,lr1;每块max_iter25/max_eval35;64帧分块累积全序列梯度。"],
33
+ ["停止条件", "tolerance_grad=1e-7,tolerance_change=1e-11,块间loss变化阈值1e-8 mm²。"]
34
+ ]
35
+ },
36
+ {
37
+ "title": "覆盖与读取",
38
+ "headers": ["项目", "说明"],
39
+ "rows": [
40
+ ["方法参考样本", "s7/camera_browse_1,275个30fps交付帧;原始帧0…1096、步长4。仅为方法参考,不是全GRAB完成凭据。"],
41
+ ["参考误差", "该样本平均顶点误差:左2.6361mm、右2.0381mm;不能外推为全部序列误差。"],
42
+ ["一起保存", "betas_fitted、global_orient_fitted、fullpose_fitted、transl_source、source_frame_indices。"],
43
+ ["渲染基线", "1536×864、30fps、Cycles OptiX16SPP、GPU OIDN、DLSS5 Feature18、motion/depth/class时序门、history0.9、最终CRF10。"],
44
+ ["标签属性", "fit_only=true;拟合beta不是原始shape GT,拟合pose不是原始pose GT;RGB仍由原始个体化几何决定。"]
45
+ ]
46
+ }
47
+ ],
48
+ "limits": ["方法参考的误差和合同不代表全部序列拟合、视觉或训练资格通过。", "拟合pose必须与同次拟合beta及原translation配套,不能与原始pose随意交叉组合。"]
49
+ },
50
+ {
51
+ "id": "002",
52
+ "delta": "增加LingBot-Depth论文启发的主动双目深度试验。复用原RGB和原几何,不是对GT逐像素加高斯噪声。",
53
+ "groups": [
54
+ {
55
+ "title": "光学与噪声",
56
+ "headers": ["项目", "试验配置"],
57
+ "rows": [
58
+ ["双目", "校正双目768×432,基线0.05m;共享投影器位于左相机右侧0.025m。"],
59
+ ["散斑投影", "1024×1024图案、20,000点、seed20261013、12W;Cycles16SPP,IR不去噪。"],
60
+ ["材料", "原可见光BSDF的灰度亮度代理;没有实测近红外反射率。"],
61
+ ["成像噪声", "光学Gaussian blur σ=0.45px;满量程1,800光电子的Poisson散粒噪声;3电子读出噪声;匹配前量化为8bit。"],
62
+ ["输出范围", "0.15–8m;左相机轴向Z,单位米;0为无效,保留缺测。"]
63
+ ]
64
+ },
65
+ {
66
+ "title": "匹配算法",
67
+ "headers": ["项目", "数值设置"],
68
+ "rows": [
69
+ ["实现", "OpenCV StereoSGBM MODE_HH,8路径;不是LingBot作者发布的原始模拟器。"],
70
+ ["视差与代价", "minDisparity0、numDisparities160、blockSize3、P1=72、P2=288、uniquenessRatio10。"],
71
+ ["过滤", "speckleWindow80、speckleRange2、disp12MaxDiff1、左右一致性容差1px。"],
72
+ ["几何", "Z=fx×baseline/disparity;GT不进入匹配、残差筛选或填洞。"]
73
+ ]
74
+ },
75
+ {
76
+ "title": "覆盖与读取",
77
+ "headers": ["范围", "说明"],
78
+ "rows": [
79
+ ["s4/cubesmall_pass_1", "试验帧50、85、110。"],
80
+ ["s6/wineglass_pass_1", "试验帧77、85、162。"],
81
+ ["RGB", "复用已完成Feature18/history0.9/CRF10输出,保留原渲染批次身份。"],
82
+ ["深度", "独立读取深度与valid;不是RGB后处理效果,也不是硬件采集值。"]
83
+ ]
84
+ }
85
+ ],
86
+ "limits": ["有限试验没有启用全量生产;不能把V005全部GRAB标为已拥有V002模拟深度。", "调用方自行选择的参数与可见光材质代理不是商业相机标定。"],
87
+ "references": [["LingBot-Depth §3.1", "https://arxiv.org/html/2601.17895v1#S3.SS1"], ["LingBot官方仓库", "https://github.com/Robbyant/lingbot-depth/tree/f3a237e434ae987bc38281476d6cfb5df3e4d739"]]
88
+ },
89
+ {
90
+ "id": "003",
91
+ "delta": "另一个有限深度分支:PromptDA论文启发的稀疏锚点插值。与V002主动双目是不同方法,不是一次SGM升级。",
92
+ "groups": [
93
+ {
94
+ "title": "稀疏观测与插值",
95
+ "headers": ["项目", "具体设置"],
96
+ "rows": [
97
+ ["原生网格", "H192×W256;16:9输入等比缩放为144×256,上下各24无效行,非拉伸。"],
98
+ ["下采样", "depth用最近像素,RGB用area average;采样前不混合合成深度。"],
99
+ ["锚点", "7px网格,seed20261013;XY均匀扰动±2.1px;全序列共享同一网格,保留锚点原值。"],
100
+ ["特征", "[x/W,y/H,R,G,B],RGB归一化到[0,1];空间和RGB feature scale均0.12。"],
101
+ ["近邻", "scipy.spatial.cKDTree精确KNN,K=8;特征距离平方的倒数加权平均,epsilon1e-8。"],
102
+ ["输出对齐", "移除letterbox后最近邻上采样至干净深度网格;float32 camera-Z米,0无效。"],
103
+ ["GT依赖", "GT只提供稀疏锚点读数,不用完整GT残差、边缘引导或后验校正。"],
104
+ ["不使用", "SGM、双目、Gaussian depth noise、学习式PromptDA模型或真实iPhone标定。"]
105
+ ]
106
+ },
107
+ {
108
+ "title": "覆盖与读取",
109
+ "headers": ["项目", "说明"],
110
+ "rows": [
111
+ ["来源", "复用V002两条GRAB动作的6个试验帧及RGB;原手、身体、衣物、物体和相机不变。"],
112
+ ["分别保留", "干净深度、原生低分辨率观测、稀疏锚点、上采样结果和valid。"],
113
+ ["confidence", "最近锚点feature distance只是诊断量,不是Apple置信度或物理传感器置信度。"],
114
+ ["自行选定的参数", "网格扰动、K、RGB/XY度量、权重、下采样、letterbox及跨帧固定网格均为本项目明确选择。"]
115
+ ]
116
+ }
117
+ ],
118
+ "limits": ["这是论文启发的复现,不是作者原始LiDAR模拟器;未启用全量生产。", "V003观测不能和V002/V006的独立双目测量混为同一噪声分布。"],
119
+ "references": [["PromptDA §3.3", "https://arxiv.org/html/2412.14015v2#S3.SS3"], ["官方代码讨论", "https://github.com/DepthAnything/PromptDA/issues/17#issuecomment-2589738069"]]
120
+ },
121
+ {
122
+ "id": "004",
123
+ "delta": "只修正标准左MANO的形状基底符号,并在单序列上重做左手拟合;不是新的人体、衣物或RGB批次。",
124
+ "groups": [
125
+ {
126
+ "title": "左手修正",
127
+ "headers": ["项目", "具体设置"],
128
+ "rows": [
129
+ ["唯一基底操作", "加载标准左MANO后在内存执行一次 shapedirs[:,0,:] *= -1;不改原始pkl或个体化目标。"],
130
+ ["范围", "s7/camera_browse_1左手,275个交付帧;source0…1096、step4。"],
131
+ ["右手", "逐字节复用已完成V001参数,不重新拟合、不改右手基底。"],
132
+ ["优化", "共享beta10+逐帧pose48;纯对应顶点均匀L2;固定translation;同V001 float64 L-BFGS容差。"],
133
+ ["初始化", "修正基底的零姿态非居中模板最小二乘beta+原始逐帧完整pose。"],
134
+ ["没有新增", "joint loss、prior、时序平滑、角度上界、腕部对齐或显示阶段额外对齐。"],
135
+ ["读取要求", "左手beta和pose必须搭配同一修正基底解码;翻转零次或两次都不符合该合同。"]
136
+ ]
137
+ }
138
+ ],
139
+ "limits": ["单序列试验未切换全部2,425包的current入口;��量推广发生在V005。", "叠加预览沿用原RGB和K/R/T;预览不是新的合成渲染。"]
140
+ },
141
+ {
142
+ "id": "005",
143
+ "delta": "将V004左手基底修正推广到收到的完整GRAB交付范围。REPLACEMENT_COMPLETE指拟合参数附件替换完成,不是全部RGB重新生成。",
144
+ "groups": [
145
+ {
146
+ "title": "标签更新",
147
+ "headers": ["项目", "具体行为"],
148
+ "rows": [
149
+ ["左手", "每原始序列共享beta10、逐帧pose48;纯778对应顶点等权L2;原translation固定;修正shapedirs一次。"],
150
+ ["右手", "V001 beta、pose、translation逐字节复用;V004已完成参考左手也直接复用。"],
151
+ ["求解", "float64 L-BFGS strong_wolfe,history50,每块25步,64帧累积全时间轴梯度;无prior、joint loss、时序平滑或额外腕部对齐。"],
152
+ ["没有修改", "RGB、相机、历史深度、mask、原始MANO、已有contact label、源帧和原渲染批次身份。"],
153
+ ["读取入口", "mano_fit_current.json → mano_beta_pose_fit_only_v005.npz;按附件引用和原帧映射读取。"],
154
+ ["参数属性", "辅助拟合、非原始shape/pose GT;左手必须配修正基底,右手使用不变的标准基底。"]
155
+ ]
156
+ },
157
+ {
158
+ "title": "计数口径",
159
+ "headers": ["层级", "数量", "定义"],
160
+ "rows": [
161
+ ["具体动作名称", "30", "由文件名得到browse、drink、staple、use_fun等,不是1,314类动作,也不是官方四种intent。"],
162
+ ["基础动词", "29", "仅把use_fun合并到use,其余不变。"],
163
+ ["物体×动作", "203", "去掉录制编号和Retake后的组合。"],
164
+ ["原始录制序列", "1,314", "subject+完整recording ID;10个受试者、51种物体名称前缀,含18条Retake。"],
165
+ ["渲染视频", "2,425", "source+render observation;203源各1份,1,111源各2份。"],
166
+ ["独立源时间轴帧", "398,020", "主线1,314源的30fps交付帧之和。"],
167
+ ["渲染视频帧", "740,495", "主线398,020+历史观测342,475;不是新增独立动作帧覆盖。"]
168
+ ],
169
+ "notes": ["30个具体动作名称:browse、brush、call、chop、clean、cook、drink、eat、fly、inspect、lift、offhand、on、open、pass、peel、play、pour、screw、see、set、shake、squeeze、stamp、staple、takepicture、toast、use、use_fun、wear。"]
170
+ },
171
+ {
172
+ "title": "全部渲染批次",
173
+ "headers": ["任务批次", "视频 / 帧", "相机 / RGB效果", "主要区别"],
174
+ "rows": [
175
+ ["grab_oakink_latest_production_v2", "37 / 12,431", "眼部、额头或胸前;sensor_look.v2", "强seed场景、桌面杂物、独立外观组合。名称含oakink,但此HF范围全部来源于GRAB。"],
176
+ ["grab_oakink_latest_production_v3", "253 / 81,242", "同v2相机与sensor_look.v2", "修复离屏motion vector的fp16溢出传输及共享资源准入;不是画质升级。"],
177
+ ["grab_recipe_production_v4", "1,024 / 304,347", "同v2相机与sensor_look.v2", "可放置recipe布局、明确皮肤/衣物/物体材质绑定;含2条capture_context_v1例外。"],
178
+ ["grab_seeded_remaining_production_v6", "1,111 / 342,475", "near-head;film_look.v1", "较早的慢速、小幅相机;全部是上面主线已经覆盖的源序列,新增源序列数为0。"]
179
+ ],
180
+ "notes": ["前三批在源身份上互不重叠,共1,314条。末批提供额外观测;四个批次都属于HF Ver.005。", "v4两条例外为s6/doorknob_lift、s6/doorknob_use_1,已包含在1,024内,不另加计数。"]
181
+ },
182
+ {
183
+ "title": "所有2,425视频共有的渲染设置",
184
+ "headers": ["项目", "冻结值"],
185
+ "rows": [
186
+ ["输出 / 引擎", "1536×864、30fps;Cycles OptiX、16SPP。"],
187
+ ["DLSS5", "实际Feature18,scale1.0、style default、intensity1.0、tone2.0、structure2.0。"],
188
+ ["时序 / 编码", "history0.9;DLSS中间视频CRF18;最终H.264、yuv420p、medium、CRF10。不能把中间CRF18当成最终RGB。"],
189
+ ["渲染几何", "原受试者SMPL-X与原始个体化MANO;不是拟合标准MANO或SOMA驱动渲染。"]
190
+ ]
191
+ },
192
+ {
193
+ "title": "相机与RGB效果差异",
194
+ "headers": ["属性", "主线1,314视频", "历史v6的1,111视频"],
195
+ "rows": [
196
+ ["机位", "眼部442、额头432、胸前440;每视频只用其选定的一个机位。", "near-head 1,111。"],
197
+ ["实际lens_mm", "18mm全部一致;sampled_lens_mm不等于实际应用焦距。", "12–19.49863mm,包含取景修复后的实际值。"],
198
+ ["平移半径 / 周期", "实测约0.03598–0.20352m / 1.4–4.0s。", "约0.02531–0.08536m / 4.0–10.0s。"],
199
+ ["yaw半径 / 旋转周期", "约8–20° / 1.6–4.2s。", "约4–12° / 5.0–11.0s。"],
200
+ ["随机化", "平移与旋转独立seed;围绕序列工作区,不持续锁定手或物体。", "同样独立T/R随机,不是静态或不随机。"],
201
+ ["RGB处理", "sensor_look.v2:向量快门模糊、深度相关失焦、对焦游移、曝光/白平衡漂移、色差、镜头污渍、暗角、颗粒。", "film_look.v1:暗角、颗粒、halation;没有主线的深度/对焦/快门/曝光分支。"],
202
+ ["强度分布", "mild395、regular587、strong332;不是每条都用最强效果。", "无主线severity字段,不能强行归到strong。"],
203
+ ["对焦目标", "HOI物体788、人体352、桌面174;不是所有帧都保证手最清晰。", "没有主线对焦目标统计。"],
204
+ ["颗粒sigma", "观察约0.002–0.012。", "0.001–0.003。"]
205
+ ],
206
+ "notes": ["这些范围是已生成计划的观察极值,包含取景修复,不是未经改变的均匀采样区间。逐帧K和外参是实际标定依据。", "RGB效果修改图像,而标注描述干净几何;没有据此宣称额外几何镜头畸变。"]
207
+ },
208
+ {
209
+ "title": "场景与外观",
210
+ "headers": ["主线实际场景", "视频数", "主线实际场景", "视频数"],
211
+ "rows": [
212
+ ["compact_terrazzo_kitchen", "115", "covered_paver_patio", "146"],
213
+ ["timber_studio_dining", "137", "rooftop_concrete_terrace", "123"],
214
+ ["narrow_mosaic_breakfast_room", "129", "grass_garden_terrace", "127"],
215
+ ["concrete_workshop", "142", "cobble_park_edge", "126"],
216
+ ["brick_loft_cafe", "130", "asphalt_street_market", "139"]
217
+ ],
218
+ "notes": ["主线653室内、661室外;每序列seed选择房间尺寸、材质、HDRI/灯光、家具和杂物。skin、shirt、pants、HOI材质分别独立选择索引0…9。", "i00_daylight_anchor、i01_sage_morning、i02_cool_overcast、i03_warm_evening、i04_mixed_daylight、o00_patio_anchor、o01_bright_patio、o02_cool_patio、o03_sunny_patio、o04_soft_patio是recipe参考名,不表示每源渲染10遍或固定10间相同房间。", "历史v6未验证的逐房间材质统计不补猜;只报告有冻结证据的相机、look和RGB绑定。"]
219
+ },
220
+ {
221
+ "title": "跨批次重复与划分",
222
+ "headers": ["核查项", "1,111个双观测源的结果"],
223
+ "rows": [
224
+ ["RGB文件SHA", "1,111组不同,0组相同;不是两份完全相同RGB。此结论是文件身份核查,不等于全视频逐像素解码比较。"],
225
+ ["相机NPZ SHA", "1,111组不同。"],
226
+ ["原始MANO / V005拟合SHA", "两类参数各自在全部1,111组内相同;同源动作与标签复用,不是两倍姿态覆盖。"],
227
+ ["s1/stapler_staple_2", "同一270帧动作:v4的i01_sage_morning与历史v6的o04_soft_patio,图像和相机不同,V005拟合相同。"],
228
+ ["训练划分", "先按原始subject+recording分组再划分train/val/test;不同渲染观测不能跨边界造成动作泄漏。"]
229
+ ]
230
+ },
231
+ {
232
+ "title": "文件布局与读取",
233
+ "headers": ["通道", "主线v2/v3/v4", "历史v6"],
234
+ "rows": [
235
+ ["RGB", "rgb.mp4", "rgb.mp4"],
236
+ ["相机", "camera_parameters.npz", "camera/camera_parameters.npz"],
237
+ ["原始MANO", "mano_parameters.npz", "mano_params_30fps.npz"],
238
+ ["深度", "inverse_depth_float16.npz", "depth/inverse_depth_float16.npz"],
239
+ ["可见分割", "masks_visible_2bit.npz", "逐帧human/table/hoi_object mask PNG"],
240
+ ["当前拟合", "mano_fit_current.json指向V005附件;不可替代原始MANO。", "同一源共享V005拟合;具体附件按current引用定位。"]
241
+ ],
242
+ "notes": ["历史深度是逆camera-Z:只对有限正逆深度取倒数恢复Z,并沿用文件valid与source clock;不是距离射线长度,也不是后来V006的带噪深度。", "RGB的sensor_look指成像效果,不表示包内有主动双目传感器深度。该HF Ver.005没有后来V006的成对GT+带噪深度回填。"]
243
+ },
244
+ {
245
+ "title": "核查范围",
246
+ "headers": ["证据", "实际完成范围"],
247
+ "rows": [
248
+ ["HF冻结版本", "271e98f637d12fc16375fa1b72ae42983ad0c4f6。"],
249
+ ["完整文件索引", "57份压缩manifest的SHA、条数、字节总量全部核对:1,080,277文件记录,237,682,594,527索引payload bytes。"],
250
+ ["全部渲染配置", "2,425份渲染sidecar;1,314份主线的RGB/相机/metadata与HF manifest绑定一致;1,111份历史look字节与嵌入相机计划指纹一致。"],
251
+ ["没有做", "没有下载重hash整套约240GB payload,没有新增抽帧、重渲染、拟合或把索引核查冒充视觉验收。"]
252
+ ]
253
+ }
254
+ ],
255
+ "limits": ["1,314是录制序列数,不是动作类别;2,425是渲染视频数,不是独立动作数。", "同一个渲染视���在标签更新前后RGB不变,不代表不同批次渲染的RGB相同。", "另一个V006 GRAB主线选取1,314份、每源1份;不能拿它覆盖本HF Ver.005的2,425观测口径。"],
256
+ "references": [["HF Ver.005仓库(需获准访问)", "https://huggingface.co/datasets/WhynotGPT/EgoRenderer-Ver005"], ["冻结release_manifest", "https://huggingface.co/datasets/WhynotGPT/EgoRenderer-Ver005/blob/271e98f637d12fc16375fa1b72ae42983ad0c4f6/release_manifest.json"], ["GRAB官方intent定义", "https://github.com/otaheri/GRAB"]]
257
+ },
258
+ {
259
+ "id": "006",
260
+ "delta": "当前原生手部合成数据合同:每条源动作只生产一份强随机化观测;干净GT和主动双目噪声深度都保留并快速压缩。",
261
+ "groups": [
262
+ {
263
+ "title": "数据与几何权威",
264
+ "headers": ["项目", "当前规则"],
265
+ "rows": [
266
+ ["ARCTIC", "301公开源序列、218,273源帧;原始SMPL-X身体与原始MANO手,采用279批准腕部表面。301生成终态不代表全部训练资格确认。"],
267
+ ["OakInk2", "622源序列、1,002,995既有30fps帧为目标;采用275人体/276衣物/289批准原生手资产,生成的下半身明确为非原始GT。"],
268
+ ["资产范围", "OakInk2启动时571资产就绪、51待上游,属2026-11-02资产快照;当前数量看独立实时进度,不在静态说明伪装更新。"],
269
+ ["手部", "渲染使用各数据集原始提供的手几何与参数;拟合MANO/SOMA只作独立辅助附件,不参与渲染。"],
270
+ ["来源绑定", "actor+canonical surface+cloth+source clock+scene+camera+seed绑定;旧motion中的过时UV/head字段不能覆盖批准表面。"],
271
+ ["GRAB", "1,314源的V006深度回填是独立任务;脚本准备不等于已生成新深度。不要与HF Ver.005的2,425历史视频混数。"]
272
+ ]
273
+ },
274
+ {
275
+ "title": "RGB与随机化",
276
+ "headers": ["项目", "当前规则"],
277
+ "rows": [
278
+ ["画质基线", "1536×864、30fps;Cycles OptiX16SPP+GPU OIDN;实际DLSS5 Feature18;history0.9;最终H.264 CRF10。"],
279
+ ["每源生产次数", "1个source→1个固定seed→1份当前包;slot1只是内部身份。未启动的slot2/3已经取消。"],
280
+ ["相机", "眼/额/胸为随机选项,不是每源三个机位全跑;平移与旋转扰动独立;保留源运动和逐帧标定。"],
281
+ ["场景", "seed控制环境、光照、材质、道具及相机;布局避开原HOI,无法放置的可选道具明确记录而非阻断源动作。"],
282
+ ["历史额外包", "已有2份额外变体不覆盖、不删除,记入historical_extra_complete,不计入当前301目标。"],
283
+ ["随机化与标注", "不重新采样源动作、修改原手或物体运动;干净几何标注与后处理RGB的语义分开。"]
284
+ ]
285
+ },
286
+ {
287
+ "title": "主动双目模拟深度",
288
+ "headers": ["阶段", "具体配置与边界"],
289
+ "rows": [
290
+ ["方法来源", "LingBot-Depth §3.1启发,复用V002光学噪声与SGM;所核官方代码commit未公开模拟器,不声称作者原版。"],
291
+ ["相机", "保留RGB原始K和轨迹;IR取RGB的0.75分辨率,1536×864对应1152×648;不强行套论文16–28mm焦距。"],
292
+ ["基线", "每序列seed采样0.05–0.20m,沿相机局部X轴建立校正双目;投影器在两者中点。"],
293
+ ["散斑 / 光学", "20,000点、1024图案、12W、IR16SPP且不去噪;可见光BSDF灰度代理;σ0.45px blur、1,800光电子散粒噪声、3电子读噪、8bit观测。"],
294
+ ["匹配", "8路径HH SGBM,block3、P1=72/P2=288、uniqueness10、speckle80/range2、LR容差1px;视差档位按fx/基线/最近范围决定,上限384。"],
295
+ ["GPU实现", "资格化CUDA实现对齐OpenCV4.12 HH数值合同;保留原CPU median3/speckle过滤。CPU/GPU一致只证明实现一致,不证明真实传感器逼真。"],
296
+ ["输出", "Z=fx×baseline/disparity;范围0.15–8m,缺测保留;最近邻回RGB网格,不读取GT来匹配、修正或填洞。"],
297
+ ["物理边界", "不是某型号商用IR/ToF相机标定;缺测、边界错误和噪声属于模拟观测,不能当原始深度GT。"]
298
+ ]
299
+ },
300
+ {
301
+ "title": "双深度格式",
302
+ "headers": ["通道", "文件与表示", "语义"],
303
+ "rows": [
304
+ ["干净GT", "depth_gt_mm.npz;每帧uint16/32/64自适应、1mm量化。", "无模拟传感器噪声;允许远背景超过65.535m而不静默截断。GT不是必须保留原始大浮点数组。"],
305
+ ["噪声观测", "depth_sensor_u16.npz;uint16毫米、0无效。", "主动双目估计,不是GT;独立valid保留孔洞。"],
306
+ ["压缩", "标准NPZ、libdeflate level1;逐帧压缩成员+bit-packed valid。", "速度优先;压缩本身无损,毫米量化有损,两者不要混淆。"],
307
+ ["训练读取", "DepthReader.frame(i)→float32米、valid、source_frame。", "每DataLoader进程长期持有reader,避免每帧重新打开整个序列。"],
308
+ ["历史兼容", "以每包depth_bundle/metadata和实际文件为准。", "旧float归档及sensor-only历史不能重命名成当前合格双深度;两条旧ARCTIC GT缺口另列。"]
309
+ ]
310
+ },
311
+ {
312
+ "title": "标注与时钟",
313
+ "headers": ["通道", "读取规则"],
314
+ "rows": [
315
+ ["相机", "camera_parameters.npz含K、world_to_camera/camera_to_world、图像大小、frame_index和source_frame_index;按坐标约定只变换一次。"],
316
+ ["分割", "masks_visible_2bit.npz,按classes与bitorder解码;可见分割不是contact label。"],
317
+ ["ARCTIC手", "mano_parameters.npz保留原生旋转、pose、trans、shape与源帧,不混入辅助拟合。"],
318
+ ["OakInk2手", "原生wxyz四元数及native_mano_descriptor.json;不重命名为ARCTIC轴角。"],
319
+ ["OakInk2物体", "native_object_poses.npz、object_membership.npz保留多物体ID、姿态、成员关系;按descriptor变换链及source_to_world使用。"],
320
+ ["原始时间轴", "OakInk2另存source_offsets.npy;30fps序列下标和原始source offset是不同层级。"],
321
+ ["历史路径", "artifact_locations.json+DatasetLocations;先校验原JSON SHA,再显式解析历史路径,不改immutable引用。"]
322
+ ]
323
+ },
324
+ {
325
+ "title": "执行修订与吞吐",
326
+ "headers": ["修订", "改变什么", "没有改变什么"],
327
+ "rows": [
328
+ ["279", "ARCTIC腕部批准表面与原始MANO接入。", "这是上游资产交付,不是301最终RGB已经完成。"],
329
+ ["299及后续", "资格化GPU SGBM并行和缓存/打包改进。", "保留HH匹配数值合同,不是换更粗糙的深度算法。"],
330
+ ["320", "15条Hard Case:双手交叉、真实镜面、多人各5条。", "独立于主301目标;不是额外动作类别覆盖声明。"],
331
+ ["339–340", "恢复成对GT/噪声并对GT自适应毫米量化。", "333–338历史sensor-only不再是当前交付策略。"],
332
+ ["349–350", "双通道写入、预读、SSD+NAS自适应并行。", "不扩物理GPU令牌,不放宽200GiB安全底线。"],
333
+ ["351–353", "每源只生产一次、保留渲染帧断点恢复、ARCTIC生成队列收尾。", "生成完成不代表两条历史GT缺口和辅助标签资格已解决。"],
334
+ ["354–355", "OakInk原生四元数与多物体适配。", "不重新拟合手、生成衣物或恢复旧人体队列。"],
335
+ ["356", "原NAS父预留覆盖子任务、容量预测和短序列回填;SSD896GiB总预算。", "原source/render/camera/depth数值不变;不据此声称每条10分钟。"]
336
+ ]
337
+ },
338
+ {
339
+ "title": "独立样例与准备分支",
340
+ "headers": ["分支", "范围", "边界"],
341
+ "rows": [
342
+ ["Hard Cases", "15条、10,838主源帧,全序列完整通道。", "双手交叉来自公开真实动作;镜面为场景物理镜子、可带seed污渍;多人各自保留源时钟。镜面GT为首交点而非镜后虚像距离。"],
343
+ ["单目鱼眼", "仅脚本准备:默认180°、1024方图、equidistant。", "未全量部署;GT是ray distance而非pinhole camera-Z;无已资格噪声深度/DLSS,不纳入当前V006 complete索引。"]
344
+ ]
345
+ }
346
+ ],
347
+ "limits": ["渲染/深度完成、上游资产批准、辅助拟合齐全、逐帧质量验收和训练资格是不同状态;不合并成一个PASS。", "ARCTIC38条隐藏test GT不公开,不伪造;301公开动作覆盖不等于所有官方相机视角图像都重新渲染。", "当前索引只数每源一份;train/val/test按原始source分组,历史变体和Hard Case不能导致同源泄漏。", "SSD/NAS和GPU优化不等于已达到十分钟端到端目标,吞吐比较应按源帧数和完整worker耗时。"],
348
+ "references": [["实时进度", "https://huggingface.co/datasets/DarthSoluke/EgoRendererStatus"], ["ARCTIC发布仓库", "https://huggingface.co/datasets/DarthSoluke/EgoRenderer-V006-ARCTIC"], ["LingBot-Depth §3.1", "https://arxiv.org/html/2601.17895v1#S3.SS1"]]
349
+ }
350
+ ]
351
+ }
data/egorender.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "updated": "2026-11-02",
3
  "status_url": "https://huggingface.co/datasets/DarthSoluke/EgoRendererStatus/resolve/main/status.json",
4
  "release": "V006",
5
  "versions": [
@@ -23,7 +23,8 @@
23
  ["350","SSD+NAS","NAS并行1至4条自适应;保留完整父预留,双目临时缓冲占256MiB SSD。" ],
24
  ["351","每动作只生产一次","只调度slot1;取消600个未启动额外变体,已完成2份额外结果保留为历史,不计入301目标。"],
25
  ["352–353","ARCTIC收尾","容量感知桌面摆放和断点恢复;301条生成队列终态,不代表历史GT缺口或辅助标签已全部补齐。"],
26
- ["354–355","OakInk2生产","独立原生四元数手/多物体适配;571条资产就绪、51条待上游,每源只生产一次;首条318帧已完整归档后展开四卡调度。"]
 
27
  ],
28
  "channels": [
29
  ["RGB","rgb.mp4","1536×864 · 30fps","最终后处理图像,不是raw辐射度;以包内metadata为准。"],
 
1
  {
2
+ "updated": "2026-11-03",
3
  "status_url": "https://huggingface.co/datasets/DarthSoluke/EgoRendererStatus/resolve/main/status.json",
4
  "release": "V006",
5
  "versions": [
 
23
  ["350","SSD+NAS","NAS并行1至4条自适应;保留完整父预留,双目临时缓冲占256MiB SSD。" ],
24
  ["351","每动作只生产一次","只调度slot1;取消600个未启动额外变体,已完成2份额外结果保留为历史,不计入301目标。"],
25
  ["352–353","ARCTIC收尾","容量感知桌面摆放和断点恢复;301条生成队列终态,不代表历史GT缺口或辅助标签已全部补齐。"],
26
+ ["354–355","OakInk2生产","独立原生四元数手/多物体适配;启动时571条资产就绪、51条待上游,每源只生产一次。"],
27
+ ["356","容量感知准入","绑定完整NAS父预留、容量预测和短源回填;896GiB SSD总预算和200GiB底线不变,数值渲染不变。"]
28
  ],
29
  "channels": [
30
  ["RGB","rgb.mp4","1536×864 · 30fps","最终后处理图像,不是raw辐射度;以包内metadata为准。"],
deployment_manifest.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "repo_id": "DarthSoluke/EgoNetDatasetResearch",
3
  "repo_type": "space",
4
- "base_revision": "271b60d78b782209425e16c519385ea78a3f49f2",
5
  "sdk": "static",
6
  "app_file": "index.html",
7
  "original_archive_sha256": "9d437cf8f781dd25354e3de6bdccf4a3e63c5eeb01efab5943ecfee709769160",
@@ -22,8 +22,8 @@
22
  },
23
  {
24
  "path": "README.md",
25
- "bytes": 3946,
26
- "sha256": "4eb14367b0aadb5142bbc80138b41d15af5a0e707ff135d84ced25237f49d224"
27
  },
28
  {
29
  "path": "data/datasets.json",
@@ -40,10 +40,15 @@
40
  "bytes": 105511,
41
  "sha256": "3cd64b38525a68bd5c8b584f1f702b996c1316e54ce464c1ac9b58d2bfd2cf1f"
42
  },
 
 
 
 
 
43
  {
44
  "path": "data/egorender.json",
45
- "bytes": 8993,
46
- "sha256": "e405123c3d025694db2c9ef14e5867ae52b714c4b8e00b82d29e837dd39c07db"
47
  },
48
  {
49
  "path": "data/figures.json",
@@ -85,10 +90,15 @@
85
  "bytes": 5205,
86
  "sha256": "14e89b041942ac37d3bd199b7b320968d76cebec1893ad117e50f3f6c405435e"
87
  },
 
 
 
 
 
88
  {
89
  "path": "index.html",
90
- "bytes": 3186,
91
- "sha256": "f7936f1204115078896a97c78125c8e0886ea736ef05b2d9868231b7f9cc5456"
92
  },
93
  {
94
  "path": "media/.gitkeep",
@@ -1442,8 +1452,8 @@
1442
  },
1443
  {
1444
  "path": "src/app.js",
1445
- "bytes": 6510,
1446
- "sha256": "54107cb0dd72581688d02afa2642fd48e11d305ee369d1e01933cf2cade4dd62"
1447
  },
1448
  {
1449
  "path": "src/catalog.js",
@@ -1452,8 +1462,8 @@
1452
  },
1453
  {
1454
  "path": "src/page.html",
1455
- "bytes": 3186,
1456
- "sha256": "f7936f1204115078896a97c78125c8e0886ea736ef05b2d9868231b7f9cc5456"
1457
  },
1458
  {
1459
  "path": "src/preview.js",
@@ -1472,13 +1482,13 @@
1472
  },
1473
  {
1474
  "path": "src/synthetic.css",
1475
- "bytes": 8517,
1476
- "sha256": "fa27f7a35f3c61fbbeb2c65d52a3a025c7542c9fa405595532d93a36361f5c48"
1477
  },
1478
  {
1479
  "path": "src/synthetic.js",
1480
- "bytes": 25118,
1481
- "sha256": "c4ae1b7df70fd06a6a14fd96913cd62c6752db7c4e9f04504703e522682f3c74"
1482
  },
1483
  {
1484
  "path": "src/ui.js",
@@ -1490,6 +1500,11 @@
1490
  "bytes": 357796,
1491
  "sha256": "3411692820cb8d47543f69496aa25fd603a358f4498046f41c508a5a3342210e"
1492
  },
 
 
 
 
 
1493
  {
1494
  "path": "tools/add_preview.py",
1495
  "bytes": 3048,
@@ -1570,5 +1585,30 @@
1570
  "upstream_pending": 51,
1571
  "native_hand_format": "wxyz quaternion",
1572
  "production_control_api": false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1573
  }
1574
  }
 
1
  {
2
  "repo_id": "DarthSoluke/EgoNetDatasetResearch",
3
  "repo_type": "space",
4
+ "base_revision": "aedecdabce230bff3cbc832d46e7627707091a1b",
5
  "sdk": "static",
6
  "app_file": "index.html",
7
  "original_archive_sha256": "9d437cf8f781dd25354e3de6bdccf4a3e63c5eeb01efab5943ecfee709769160",
 
22
  },
23
  {
24
  "path": "README.md",
25
+ "bytes": 4866,
26
+ "sha256": "cad50c533f716a31c4be955e3caa7ab924c88715cb42c57c206943a9eb63a1a1"
27
  },
28
  {
29
  "path": "data/datasets.json",
 
40
  "bytes": 105511,
41
  "sha256": "3cd64b38525a68bd5c8b584f1f702b996c1316e54ce464c1ac9b58d2bfd2cf1f"
42
  },
43
+ {
44
+ "path": "data/egorender-versions.json",
45
+ "bytes": 29705,
46
+ "sha256": "51f226391cf8745f22aaccdac520c2ece3efe876fea40749746116a444c5fb56"
47
+ },
48
  {
49
  "path": "data/egorender.json",
50
+ "bytes": 9109,
51
+ "sha256": "0e84fd6043ea9a0e3b66d9d51d8db1daf16daf7d10d0c76fb7bd885b3b6dd4da"
52
  },
53
  {
54
  "path": "data/figures.json",
 
90
  "bytes": 5205,
91
  "sha256": "14e89b041942ac37d3bd199b7b320968d76cebec1893ad117e50f3f6c405435e"
92
  },
93
+ {
94
+ "path": "downloads/egorender_versions.md",
95
+ "bytes": 27434,
96
+ "sha256": "c45f874f25aba90e46e6e8fbd22bccd2f45bf0697f0fc3e616a241a225d2aa6b"
97
+ },
98
  {
99
  "path": "index.html",
100
+ "bytes": 3166,
101
+ "sha256": "5de8a1967fc64fb5128e1aae82551cbafe8897fbf6d44b5f6015492fbaa7c1fa"
102
  },
103
  {
104
  "path": "media/.gitkeep",
 
1452
  },
1453
  {
1454
  "path": "src/app.js",
1455
+ "bytes": 6500,
1456
+ "sha256": "33346c736aa35ff1968677c78fbcca726cdd793ea40cafa339306457a960af99"
1457
  },
1458
  {
1459
  "path": "src/catalog.js",
 
1462
  },
1463
  {
1464
  "path": "src/page.html",
1465
+ "bytes": 3166,
1466
+ "sha256": "5de8a1967fc64fb5128e1aae82551cbafe8897fbf6d44b5f6015492fbaa7c1fa"
1467
  },
1468
  {
1469
  "path": "src/preview.js",
 
1482
  },
1483
  {
1484
  "path": "src/synthetic.css",
1485
+ "bytes": 9581,
1486
+ "sha256": "d49d659dae8cbfd3d6dcda260a668c366584f42ccb9f1e709e44ded5b291aed6"
1487
  },
1488
  {
1489
  "path": "src/synthetic.js",
1490
+ "bytes": 24546,
1491
+ "sha256": "53c79d1f65c5daf84fb1c0366f1a78804501b1eb5cba1fc222c453968da7ef8c"
1492
  },
1493
  {
1494
  "path": "src/ui.js",
 
1500
  "bytes": 357796,
1501
  "sha256": "3411692820cb8d47543f69496aa25fd603a358f4498046f41c508a5a3342210e"
1502
  },
1503
+ {
1504
+ "path": "src/versions.js",
1505
+ "bytes": 2429,
1506
+ "sha256": "cfcce3108514fd1e7cded7ee10c90d369135d87b9f82f632dc758df2942d4948"
1507
+ },
1508
  {
1509
  "path": "tools/add_preview.py",
1510
  "bytes": 3048,
 
1585
  "upstream_pending": 51,
1586
  "native_hand_format": "wxyz quaternion",
1587
  "production_control_api": false
1588
+ },
1589
+ "version_documentation": {
1590
+ "updated": "2026-11-03",
1591
+ "releases": [
1592
+ "001",
1593
+ "002",
1594
+ "003",
1595
+ "004",
1596
+ "005",
1597
+ "006"
1598
+ ],
1599
+ "grab_campaigns": 4,
1600
+ "production_changes": false,
1601
+ "protected_files": {
1602
+ "data/datasets.json": "ce46b635e1e7e08977c6c545f9443fa6dfbe600022dacdcf7fe9099c6ee7e7f2",
1603
+ "data/previews.json": "841f2aba69b09394f75c1645c49a8ac5f84f7dbc3439974afb24cdf7111c9fd5",
1604
+ "data/figures.json": "9b5000f5fee5db32b7d44c276c586a1a71bef02fbf6ead831ee915c2e9ac5f5b",
1605
+ "data/videos.json": "13095d6debfc8df33353c3d1825115397af17f770d01b083972b84931db5251f",
1606
+ "data/sampling.json": "b692c48e99623ff837db35581947fd8ecf310947258fd113afdbcb0d4cbf708a",
1607
+ "data/preview_pool.json": "6edf61566729d193d626d4ad1e9643796a47cc586741018b8f6eb60a3a51cb1f",
1608
+ "data/preview_sources.json": "e7d358d2939ee961968ea00dd39bd9996055526f40c7c05dc183e1ec2b7e1ea9",
1609
+ "data/egorender-progress.json": "7e75bb3f60f9abc4adf0537520d61f8240a0a44cb899af99ec4549cafaa756cd",
1610
+ "data/egorender-registry.json": "3cd64b38525a68bd5c8b584f1f702b996c1316e54ce464c1ac9b58d2bfd2cf1f",
1611
+ "downloads/egorender_reader.py": "14e89b041942ac37d3bd199b7b320968d76cebec1893ad117e50f3f6c405435e"
1612
+ }
1613
  }
1614
  }
downloads/egorender_versions.md ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # EgoRenderer Versions
2
+
3
+ 更新:2026-11-03。数据版本、历史批次与执行修订分别记录。
4
+
5
+ ## 版本对照
6
+
7
+ | 版本 | 改变什么 | RGB | 深度 | 覆盖与边界 |
8
+ | --- | --- | --- | --- | --- |
9
+ | 001 | 标准MANO参数拟合 | 原渲染不变 | 不新增深度 | 序列共享形状、逐帧姿态;辅助拟合不是原始GT。 |
10
+ | 002 | 主动双目深度试验 | 复用已完成RGB | 散斑投影+8路径SGM | 2条GRAB动作、各3帧的有限试验。 |
11
+ | 003 | 稀疏锚点深度试验 | 复用试验RGB | 稀疏GT锚点+RGB/XY插值 | 非双目、非PromptDA模型推理、非当前生产深度。 |
12
+ | 004 | 左手形状基底修正 | 原渲染不变 | 沿用原深度 | 1条动作275帧;右手复用V001。 |
13
+ | 005 | GRAB完整参数更新 | 保留各历史批次RGB | 历史逆camera-Z | 1,314原始序列,2,425个渲染视频;只更新拟合附件。 |
14
+ | 006 | 原生手强随机化合成 | 原生几何驱动新合成 | 压缩GT+主动双目噪声深度 | ARCTIC、OakInk2分开;每源1次生产,辅助拟合不驱动像素。 |
15
+
16
+ ## 命名层级
17
+
18
+ | 层级 | 例子 | 含义 |
19
+ | --- | --- | --- |
20
+ | 数据与方法版本 | V001–V006 | 拟合、深度试验与交付合同的演进;不表示每个版本都重新渲染了一套RGB。 |
21
+ | 渲染批次 | grab_recipe_production_v4 / grab_seeded_remaining_production_v6 | 历史任务名。两者都出现在HF Ver.005里,名称中的v6不等于数据发布V006。 |
22
+ | 执行修订 | 279 / 299 / 351 / 356 | 资产修复、GPU匹配、调度或打包实现;当前所属数据版本仍是V006。 |
23
+
24
+ ## V001 参数标注基线
25
+
26
+ 历史方法
27
+
28
+ 把个体化GRAB手表面映射到标准MANO参数空间,固定方法和产物命名;不改变渲染所用的原始手表面。
29
+
30
+ ### 拟合合同
31
+
32
+ | 项目 | 具体设置 |
33
+ | --- | --- |
34
+ | 目标 | 原个体化MANO在原始姿态和translation下的778个对应顶点;左右手分别求解。 |
35
+ | 优化变量 | 每手每序列共享beta10;每帧pose48=global rotation3+finger pose45,轴角弧度,非PCA,flat_hand_mean=true。 |
36
+ | 固定量 | 原逐帧translation、对应顶点索引和已明确交付的source_frame_indices;不额外抽帧。 |
37
+ | 损失 | 所有交付帧、所有778顶点等权平均平方欧氏距离;坐标为毫米,损失单位mm²。 |
38
+ | 不使用 | joint loss、beta/pose prior、时序平滑、腕部居中、额外腕部平移、强制腕部旋转对齐或姿态角上界。 |
39
+ | 初始化 | 零姿态非居中表面形状估计+原始完整pose;已有序列估计可继续,不重启已完成优化。 |
40
+ | 求解器 | float64 L-BFGS,strong_wolfe;history50,lr1;每块max_iter25/max_eval35;64帧分块累积全序列梯度。 |
41
+ | 停止条件 | tolerance_grad=1e-7,tolerance_change=1e-11,块间loss变化阈值1e-8 mm²。 |
42
+
43
+ ### 覆盖与读取
44
+
45
+ | 项目 | 说明 |
46
+ | --- | --- |
47
+ | 方法参考样本 | s7/camera_browse_1,275个30fps交付帧;原始帧0…1096、步长4。仅为方法参考,不是全GRAB完成凭据。 |
48
+ | 参考误差 | 该样本平均顶点误差:左2.6361mm、右2.0381mm;不能外推为全部序列误差。 |
49
+ | 一起保存 | betas_fitted、global_orient_fitted、fullpose_fitted、transl_source、source_frame_indices。 |
50
+ | 渲染基线 | 1536×864、30fps、Cycles OptiX16SPP、GPU OIDN、DLSS5 Feature18、motion/depth/class时序门、history0.9、最终CRF10。 |
51
+ | 标签属性 | fit_only=true;拟合beta不是原始shape GT,拟合pose不是原始pose GT;RGB仍由原始个体化几何决定。 |
52
+
53
+ ### 使用边界
54
+
55
+ - 方法参考的误差和合同不代表全部序列拟合、视觉或训练资格通过。
56
+ - 拟合pose必须与同次拟合beta及原translation配套,不能与原始pose随意交叉组合。
57
+
58
+
59
+ ## V002 主动双目深度试验
60
+
61
+ 有限试验,非全量发布
62
+
63
+ 增加LingBot-Depth论文启发的主动双目深度试验。复用原RGB和原几何,不是对GT逐像素加高斯噪声。
64
+
65
+ ### 光学与噪声
66
+
67
+ | 项目 | 试验配置 |
68
+ | --- | --- |
69
+ | 双目 | 校正双目768×432,基线0.05m;共享投影器位于左相机右侧0.025m。 |
70
+ | 散斑投影 | 1024×1024图案、20,000点、seed20261013、12W;Cycles16SPP,IR不去噪。 |
71
+ | 材料 | 原可见光BSDF的灰度亮度代理;没有实测近红外反射率。 |
72
+ | 成像噪声 | 光学Gaussian blur σ=0.45px;满量程1,800光电子的Poisson散粒噪声;3电子读出噪声;匹配前量化为8bit。 |
73
+ | 输出范围 | 0.15–8m;左相机轴向Z,单位米;0为无效,保留缺测。 |
74
+
75
+ ### 匹配算法
76
+
77
+ | 项目 | 数值设置 |
78
+ | --- | --- |
79
+ | 实现 | OpenCV StereoSGBM MODE_HH,8路径;不是LingBot作者发布的原始模拟器。 |
80
+ | 视差与代价 | minDisparity0、numDisparities160、blockSize3、P1=72、P2=288、uniquenessRatio10。 |
81
+ | 过滤 | speckleWindow80、speckleRange2、disp12MaxDiff1、左右一致性容差1px。 |
82
+ | 几何 | Z=fx×baseline/disparity;GT不进入匹配、残差筛选或填洞。 |
83
+
84
+ ### 覆盖与读取
85
+
86
+ | 范��� | 说明 |
87
+ | --- | --- |
88
+ | s4/cubesmall_pass_1 | 试验帧50、85、110。 |
89
+ | s6/wineglass_pass_1 | 试验帧77、85、162。 |
90
+ | RGB | 复用已完成Feature18/history0.9/CRF10输出,保留原渲染批次身份。 |
91
+ | 深度 | 独立读取深度与valid;不是RGB后处理效果,也不是硬件采集值。 |
92
+
93
+ ### 使用边界
94
+
95
+ - 有限试验没有启用全量生产;不能把V005全部GRAB标为已拥有V002模拟深度。
96
+ - 调用方自行选择的参数与可见光材质代理不是商业相机标定。
97
+
98
+ - [LingBot-Depth §3.1](https://arxiv.org/html/2601.17895v1#S3.SS1)
99
+ - [LingBot官方仓库](https://github.com/Robbyant/lingbot-depth/tree/f3a237e434ae987bc38281476d6cfb5df3e4d739)
100
+
101
+ ## V003 稀疏深度观测试验
102
+
103
+ 有限试验,非当前深度分支
104
+
105
+ 另一个有限深度分支:PromptDA论文启发的稀疏锚点插值。与V002主动双目是不同方法,不是一次SGM升级。
106
+
107
+ ### 稀疏观测与插值
108
+
109
+ | 项目 | 具体设置 |
110
+ | --- | --- |
111
+ | 原生网格 | H192×W256;16:9输入等比缩放为144×256,上下各24无效行,非拉伸。 |
112
+ | 下采样 | depth用最近像素,RGB用area average;采样前不混合合成深度。 |
113
+ | 锚点 | 7px网格,seed20261013;XY均匀扰动±2.1px;全序列共享同一网格,保留锚点原值。 |
114
+ | 特征 | [x/W,y/H,R,G,B],RGB归一化到[0,1];空间和RGB feature scale均0.12。 |
115
+ | 近邻 | scipy.spatial.cKDTree精确KNN,K=8;特征距离平方的倒数加权平均,epsilon1e-8。 |
116
+ | 输出对齐 | 移除letterbox后最近邻上采样至干净深度网格;float32 camera-Z米,0无效。 |
117
+ | GT依赖 | GT只提供稀疏锚点读数,不用完整GT残差、边缘引导或后验校正。 |
118
+ | 不使用 | SGM、双目、Gaussian depth noise、学习式PromptDA模型或真实iPhone标定。 |
119
+
120
+ ### 覆盖与读取
121
+
122
+ | 项目 | 说明 |
123
+ | --- | --- |
124
+ | 来源 | 复用V002两条GRAB动作的6个试验帧及RGB;原手、身体、衣物、物体和相机不变。 |
125
+ | 分别保留 | 干净深度、原生低分辨率观测、稀疏锚点、上采样结果和valid。 |
126
+ | confidence | 最近锚点feature distance只是诊断量,不是Apple置信度或物理传感器置信度。 |
127
+ | 自行选定的参数 | 网格扰动、K、RGB/XY度量、权重、下采样、letterbox及跨帧固定网格均为本项目明确选择。 |
128
+
129
+ ### 使用边界
130
+
131
+ - 这是论文启发的复现,不是作者原始LiDAR模拟器;未启用全量生产。
132
+ - V003观测不能和V002/V006的独立双目测量混为同一噪声分布。
133
+
134
+ - [PromptDA §3.3](https://arxiv.org/html/2412.14015v2#S3.SS3)
135
+ - [官方代码讨论](https://github.com/DepthAnything/PromptDA/issues/17#issuecomment-2589738069)
136
+
137
+ ## V004 左手基底修正试验
138
+
139
+ 单序列试验
140
+
141
+ 只修正标准左MANO的形状基底符号,并在单序列上重做左手拟合;不是新的人体、衣物或RGB批次。
142
+
143
+ ### 左手修正
144
+
145
+ | 项目 | 具体设置 |
146
+ | --- | --- |
147
+ | 唯一基底操作 | 加载标准左MANO后在内存执行一次 shapedirs[:,0,:] *= -1;不改原始pkl或个体化目标。 |
148
+ | 范围 | s7/camera_browse_1左手,275个交付帧;source0…1096、step4。 |
149
+ | 右手 | 逐字节复用已完成V001参数,不重新拟合、不改右手基底。 |
150
+ | 优化 | 共享beta10+逐帧pose48;纯对应顶点均匀L2;固定translation;同V001 float64 L-BFGS容差。 |
151
+ | 初始化 | 修正基底的零姿态非居中模板最小二乘beta+原始逐帧完整pose。 |
152
+ | 没有新增 | joint loss、prior、时序平滑、角度上界、腕部对齐或显示阶段额外对齐。 |
153
+ | 读取要求 | 左手beta和pose必须搭配同一修正基底解码;翻转零次或两次都不符合该合同。 |
154
+
155
+ ### 使用边界
156
+
157
+ - 单序列试验未切换全部2,425包的current入口;全量推广发生在V005。
158
+ - 叠加预览沿用原RGB和K/R/T;预览不是新的合成渲染。
159
+
160
+
161
+ ## V005 GRAB完整参数更新
162
+
163
+ 历史交付完成
164
+
165
+ 将V004左手基底修正推广到收到的完整GRAB交付范围。REPLACEMENT_COMPLETE指拟合参数附件替换完成,不是全部RGB重新生成。
166
+
167
+ ### 标签更新
168
+
169
+ | 项目 | 具体行为 |
170
+ | --- | --- |
171
+ | 左手 | 每原始序列共享beta10、逐帧pose48;纯778对应顶点等权L2;原translation固定;修正shapedirs一次。 |
172
+ | 右手 | V001 beta、pose、translation逐字节复用;V004已完成参考左手也直接复用。 |
173
+ | 求解 | float64 L-BFGS strong_wolfe,history50,每块25步,64帧累积全时间轴梯度;无prior、joint loss、时序平滑或额外腕部对齐。 |
174
+ | 没有修改 | RGB、相机、历史深度、mask、原始MANO、已有contact label、源帧和原渲染批次身份。 |
175
+ | 读取入口 | mano_fit_current.json → mano_beta_pose_fit_only_v005.npz;按附件引用和原帧映射读取。 |
176
+ | 参数属性 | 辅助拟合、非原始shape/pose GT;左手必须配修正基底,右手使用不变的标准基底。 |
177
+
178
+ ### 计数口径
179
+
180
+ | 层级 | 数量 | 定义 |
181
+ | --- | --- | --- |
182
+ | 具体动作名称 | 30 | 由文件名���到browse、drink、staple、use_fun等,不是1,314类动作,也不是官方四种intent。 |
183
+ | 基础动词 | 29 | 仅把use_fun合并到use,其余不变。 |
184
+ | 物体×动作 | 203 | 去掉录制编号和Retake后的组合。 |
185
+ | 原始录制序列 | 1,314 | subject+完整recording ID;10个受试者、51种物体名称前缀,含18条Retake。 |
186
+ | 渲染视频 | 2,425 | source+render observation;203源各1份,1,111源各2份。 |
187
+ | 独立源时间轴帧 | 398,020 | 主线1,314源的30fps交付帧之和。 |
188
+ | 渲染视频帧 | 740,495 | 主线398,020+历史观测342,475;不是新增独立动作帧覆盖。 |
189
+
190
+ 30个具体动作名称:browse、brush、call、chop、clean、cook、drink、eat、fly、inspect、lift、offhand、on、open、pass、peel、play、pour、screw、see、set、shake、squeeze、stamp、staple、takepicture、toast、use、use_fun、wear。
191
+
192
+ ### 全部渲染批次
193
+
194
+ | 任务批次 | 视频 / 帧 | 相机 / RGB效果 | 主要区别 |
195
+ | --- | --- | --- | --- |
196
+ | grab_oakink_latest_production_v2 | 37 / 12,431 | 眼部、额头或胸前;sensor_look.v2 | 强seed场景、桌面杂物、独立外观组合。名称含oakink,但此HF范围全部来源于GRAB。 |
197
+ | grab_oakink_latest_production_v3 | 253 / 81,242 | 同v2相机与sensor_look.v2 | 修复离屏motion vector的fp16溢出传输及共享资源准入;不是画质升级。 |
198
+ | grab_recipe_production_v4 | 1,024 / 304,347 | 同v2相机与sensor_look.v2 | 可放置recipe布局、明确皮肤/衣物/物体材质绑定;含2条capture_context_v1例外。 |
199
+ | grab_seeded_remaining_production_v6 | 1,111 / 342,475 | near-head;film_look.v1 | 较早的慢速、小幅相机;全部是上面主线已经覆盖的源序列,新增源序列数为0。 |
200
+
201
+ 前三批在源身份上互不重叠,共1,314条。末批提供额外观测;四个批次都属于HF Ver.005。
202
+
203
+ v4两条例外为s6/doorknob_lift、s6/doorknob_use_1,已包含在1,024内,不另加计数。
204
+
205
+ ### 所有2,425视频共有的渲染设置
206
+
207
+ | 项目 | 冻结值 |
208
+ | --- | --- |
209
+ | 输出 / 引擎 | 1536×864、30fps;Cycles OptiX、16SPP。 |
210
+ | DLSS5 | 实际Feature18,scale1.0、style default、intensity1.0、tone2.0、structure2.0。 |
211
+ | 时序 / 编码 | history0.9;DLSS中间视频CRF18;最终H.264、yuv420p、medium、CRF10。不能把中间CRF18当成最终RGB。 |
212
+ | 渲染几何 | 原受试者SMPL-X与原始个体化MANO;不是拟合标准MANO或SOMA驱动渲染。 |
213
+
214
+ ### 相机与RGB效果差异
215
+
216
+ | 属性 | 主线1,314视频 | 历史v6的1,111视频 |
217
+ | --- | --- | --- |
218
+ | 机位 | 眼部442、额头432、胸前440;每视频只用其选定的一个机位。 | near-head 1,111。 |
219
+ | 实际lens_mm | 18mm全部一致;sampled_lens_mm不等于实际应用焦距。 | 12–19.49863mm,包含取景修复后的实际值。 |
220
+ | 平移半径 / 周期 | 实测约0.03598–0.20352m / 1.4–4.0s。 | 约0.02531–0.08536m / 4.0–10.0s。 |
221
+ | yaw半径 / 旋转周期 | 约8–20° / 1.6–4.2s。 | 约4–12° / 5.0–11.0s。 |
222
+ | 随机化 | 平移与旋转独立seed;围绕序列工作区,不持续锁定手或物体。 | 同样独立T/R随机,不是静态或不随机。 |
223
+ | RGB处理 | sensor_look.v2:向量快门模糊、深度相关失焦、对焦游移、曝光/白平衡漂移、色差、镜头污渍、暗角、颗粒。 | film_look.v1:暗角、颗粒、halation;没有主线的深度/对焦/快门/曝光分支。 |
224
+ | 强度分布 | mild395、regular587、strong332;不是每条都用最强效果。 | 无主线severity字段,不能强行归到strong。 |
225
+ | 对焦目标 | HOI物体788、人体352、桌面174;不是所有帧都保证手最清晰。 | 没有主线对焦目标统计。 |
226
+ | 颗粒sigma | 观察约0.002–0.012。 | 0.001–0.003。 |
227
+
228
+ 这些范围是已生成计划的观察极值,包含取景修复,不是未经改变的均匀采样区间。逐帧K和外参是实际标定依据。
229
+
230
+ RGB效果修改图像,而标注描述干净几何;没有据此宣称额外几何镜头畸变。
231
+
232
+ ### 场景与外观
233
+
234
+ | 主线实际场景 | 视频数 | 主线实际场景 | 视频数 |
235
+ | --- | --- | --- | --- |
236
+ | compact_terrazzo_kitchen | 115 | covered_paver_patio | 146 |
237
+ | timber_studio_dining | 137 | rooftop_concrete_terrace | 123 |
238
+ | narrow_mosaic_breakfast_room | 129 | grass_garden_terrace | 127 |
239
+ | concrete_workshop | 142 | cobble_park_edge | 126 |
240
+ | brick_loft_cafe | 130 | asphalt_street_market | 139 |
241
+
242
+ 主线653室内、661室外;每序列seed选择房间尺寸、材质、HDRI/灯光、家具和杂物。skin、shirt、pants、HOI材质分别独立选择索引0…9。
243
+
244
+ i00_daylight_anchor、i01_sage_morning、i02_cool_overcast、i03_warm_evening、i04_mixed_daylight、o00_patio_anchor、o01_bright_patio、o02_cool_patio、o03_sunny_patio、o04_soft_patio是recipe参考名,不表示每源渲染10遍或固定10间相同房间。
245
+
246
+ 历史v6未验证的逐房间材质统计不补猜;只报告有冻结证据的相机、look和RGB绑定。
247
+
248
+ ### 跨批次重复与划分
249
+
250
+ | ���查项 | 1,111个双观测源的结果 |
251
+ | --- | --- |
252
+ | RGB文件SHA | 1,111组不同,0组相同;不是两份完全相同RGB。此结论是文件身份核查,不等于全视频逐像素解码比较。 |
253
+ | 相机NPZ SHA | 1,111组不同。 |
254
+ | 原始MANO / V005拟合SHA | 两类参数各自在全部1,111组内相同;同源动作与标签复用,不是两倍姿态覆盖。 |
255
+ | s1/stapler_staple_2 | 同一270帧动作:v4的i01_sage_morning与历史v6的o04_soft_patio,图像和相机不同,V005拟合相同。 |
256
+ | 训练划分 | 先按原始subject+recording分组再划分train/val/test;不同渲染观测不能跨边界造成动作泄漏。 |
257
+
258
+ ### 文件布局与读取
259
+
260
+ | 通道 | 主线v2/v3/v4 | 历史v6 |
261
+ | --- | --- | --- |
262
+ | RGB | rgb.mp4 | rgb.mp4 |
263
+ | 相机 | camera_parameters.npz | camera/camera_parameters.npz |
264
+ | 原始MANO | mano_parameters.npz | mano_params_30fps.npz |
265
+ | 深度 | inverse_depth_float16.npz | depth/inverse_depth_float16.npz |
266
+ | 可见分割 | masks_visible_2bit.npz | 逐帧human/table/hoi_object mask PNG |
267
+ | 当前拟合 | mano_fit_current.json指向V005附件;不可替代原始MANO。 | 同一源共享V005拟合;具体附件按current引用定位。 |
268
+
269
+ 历史深度是逆camera-Z:只对有限正逆深度取倒数恢复Z,并沿用文件valid与source clock;不是距离射线长度,也不是后来V006的带噪深度。
270
+
271
+ RGB的sensor_look指成像效果,不表示包内有主动双目传感器深度。该HF Ver.005没有后来V006的成对GT+带噪深度回填。
272
+
273
+ ### 核查范围
274
+
275
+ | 证据 | 实际完成范围 |
276
+ | --- | --- |
277
+ | HF冻结版本 | 271e98f637d12fc16375fa1b72ae42983ad0c4f6。 |
278
+ | 完整文件索引 | 57份压缩manifest的SHA、条数、字节总量全部核对:1,080,277文件记录,237,682,594,527索引payload bytes。 |
279
+ | 全部渲染配置 | 2,425份渲染sidecar;1,314份主线的RGB/相机/metadata与HF manifest绑定一致;1,111份历史look字节与嵌入相机计划指纹一致。 |
280
+ | 没有做 | 没有下载重hash整套约240GB payload,没有新增抽帧、重渲染、拟合或把索引核查冒充视觉验收。 |
281
+
282
+ ### 使用边界
283
+
284
+ - 1,314是录制序列数,不是动作类别;2,425是渲染视频数,不是独立动作数。
285
+ - 同一个渲染视频在标签更新前后RGB不变,不代表不同批次渲染的RGB相同。
286
+ - 另一个V006 GRAB主线选取1,314份、每源1份;不能拿它覆盖本HF Ver.005的2,425观测口径。
287
+
288
+ - [HF Ver.005仓库(需获准访问)](https://huggingface.co/datasets/WhynotGPT/EgoRenderer-Ver005)
289
+ - [冻结release_manifest](https://huggingface.co/datasets/WhynotGPT/EgoRenderer-Ver005/blob/271e98f637d12fc16375fa1b72ae42983ad0c4f6/release_manifest.json)
290
+ - [GRAB官方intent定义](https://github.com/otaheri/GRAB)
291
+
292
+ ## V006 原生手部的强随机化合成
293
+
294
+ 当前数据版本
295
+
296
+ 当前原生手部合成数据合同:每条源动作只生产一份强随机化观测;干净GT和主动双目噪声深度都保留并快速压缩。
297
+
298
+ ### 数据与几何权威
299
+
300
+ | 项目 | 当前规则 |
301
+ | --- | --- |
302
+ | ARCTIC | 301公开源序列、218,273源帧;原始SMPL-X身体与原始MANO手,采用279批准腕部表面。301生成终态不代表全部训练资格确认。 |
303
+ | OakInk2 | 622源序列、1,002,995既有30fps帧为目标;采用275人体/276衣物/289批准原生手资产,生成的下半身明确为非原始GT。 |
304
+ | 资产范围 | OakInk2启动时571资产就绪、51待上游,属2026-11-02资产快照;当前数量看独立实时进度,不在静态说明伪装更新。 |
305
+ | 手部 | 渲染使用各数据集原始提供的手几何与参数;拟合MANO/SOMA只作独立辅助附件,不参与渲染。 |
306
+ | 来源绑定 | actor+canonical surface+cloth+source clock+scene+camera+seed绑定;旧motion中的过时UV/head字段不能覆盖批准表面。 |
307
+ | GRAB | 1,314源的V006深度回填是独立任务;脚本准备不等于已生成新深度。不要与HF Ver.005的2,425历史视频混数。 |
308
+
309
+ ### RGB与随机化
310
+
311
+ | 项目 | 当前规则 |
312
+ | --- | --- |
313
+ | 画质基线 | 1536×864、30fps;Cycles OptiX16SPP+GPU OIDN;实际DLSS5 Feature18;history0.9;最终H.264 CRF10。 |
314
+ | 每源生产次数 | 1个source→1个固定seed→1份当前包;slot1只是内部身份。未启动的slot2/3已经取消。 |
315
+ | 相机 | 眼/额/胸为随机选项,不是每源三个机位全跑;平移与旋转扰动独立;保留源运动和逐帧标定。 |
316
+ | 场景 | seed控制环境、光照、材质、道具及相机;布局避开原HOI,无法放置的可选道具明确记录而非阻断源动作。 |
317
+ | 历史额外包 | 已有2份额外变体不覆盖、不删除,记入historical_extra_complete,不计入当前301目标。 |
318
+ | 随机化与标注 | 不重新采样源动作、修改原手或物体运动;干净几何标注与后处理RGB的语义分开。 |
319
+
320
+ ### 主动双目模拟深度
321
+
322
+ | 阶段 | 具体配置与边界 |
323
+ | --- | --- |
324
+ | 方法来源 | LingBot-Depth §3.1启发,复用V002光学噪声与SGM;��核官方代码commit未公开模拟器,不声称作者原版。 |
325
+ | 相机 | 保留RGB原始K和轨迹;IR取RGB的0.75分辨率,1536×864对应1152×648;不强行套论文16–28mm焦距。 |
326
+ | 基线 | 每序列seed采样0.05–0.20m,沿相机局部X轴建立校正双目;投影器在两者中点。 |
327
+ | 散斑 / 光学 | 20,000点、1024图案、12W、IR16SPP且不去噪;可见光BSDF灰度代理;σ0.45px blur、1,800光电子散粒噪声、3电子读噪、8bit观测。 |
328
+ | 匹配 | 8路径HH SGBM,block3、P1=72/P2=288、uniqueness10、speckle80/range2、LR容差1px;视差档位按fx/基线/最近范围决定,上限384。 |
329
+ | GPU实现 | 资格化CUDA实现对齐OpenCV4.12 HH数值合同;保留原CPU median3/speckle过滤。CPU/GPU一致只证明实现一致,不证明真实传感器逼真。 |
330
+ | 输出 | Z=fx×baseline/disparity;范围0.15–8m,缺测保留;最近邻回RGB网格,不读取GT来匹配、修正或填洞。 |
331
+ | 物理边界 | 不是某型号商用IR/ToF相机标定;缺测、边界错误和噪声属于模拟观测,不能当原始深度GT。 |
332
+
333
+ ### 双深度格式
334
+
335
+ | 通道 | 文件与表示 | 语义 |
336
+ | --- | --- | --- |
337
+ | 干净GT | depth_gt_mm.npz;每帧uint16/32/64自适应、1mm量化。 | 无模拟传感器噪声;允许远背景超过65.535m而不静默截断。GT不是必须保留原始大浮点数组。 |
338
+ | 噪声观测 | depth_sensor_u16.npz;uint16毫米、0无效。 | 主动双目估计,不是GT;独立valid保留孔洞。 |
339
+ | 压缩 | 标准NPZ、libdeflate level1;逐帧压缩成员+bit-packed valid。 | 速度优先;压缩本身无损,毫米量化有损,两者不要混淆。 |
340
+ | 训练读取 | DepthReader.frame(i)→float32米、valid、source_frame。 | 每DataLoader进程长期持有reader,避免每帧重新打开整个序列。 |
341
+ | 历史兼容 | 以每包depth_bundle/metadata和实际文件为准。 | 旧float归档及sensor-only历史不能重命名成当前合格双深度;两条旧ARCTIC GT缺口另列。 |
342
+
343
+ ### 标注与时钟
344
+
345
+ | 通道 | 读取规则 |
346
+ | --- | --- |
347
+ | 相机 | camera_parameters.npz含K、world_to_camera/camera_to_world、图像大小、frame_index和source_frame_index;按坐标约定只变换一次。 |
348
+ | 分割 | masks_visible_2bit.npz,按classes与bitorder解码;可见分割不是contact label。 |
349
+ | ARCTIC手 | mano_parameters.npz保留原生旋转、pose、trans、shape与源帧,不混入辅助拟合。 |
350
+ | OakInk2手 | 原生wxyz四元数及native_mano_descriptor.json;不重命名为ARCTIC轴角。 |
351
+ | OakInk2物体 | native_object_poses.npz、object_membership.npz保留多物体ID、姿态、成员关系;按descriptor变换链及source_to_world使用。 |
352
+ | 原始时间轴 | OakInk2另存source_offsets.npy;30fps序列下标和原始source offset是不同层级。 |
353
+ | 历史路径 | artifact_locations.json+DatasetLocations;先校验原JSON SHA,再显式解析历史路径,不改immutable引用。 |
354
+
355
+ ### 执行修订与吞吐
356
+
357
+ | 修订 | 改变什么 | 没有改变什么 |
358
+ | --- | --- | --- |
359
+ | 279 | ARCTIC腕部批准表面与原始MANO接入。 | 这是上游资产交付,不是301最终RGB已经完成。 |
360
+ | 299及后续 | 资格化GPU SGBM并行和缓存/打包改进。 | 保留HH匹配数值合同,不是换更粗糙的深度算法。 |
361
+ | 320 | 15条Hard Case:双手交叉、真实镜面、多人各5条。 | 独立于主301目标;不是额外动作类别覆盖声明。 |
362
+ | 339–340 | 恢复成对GT/噪声并对GT自适应毫米量化。 | 333–338历史sensor-only不再是当前交付策略。 |
363
+ | 349–350 | 双通道写入、预读、SSD+NAS自适应并行。 | 不扩物理GPU令牌,不放宽200GiB安全底线。 |
364
+ | 351–353 | 每源只生产一次、保留渲染帧断点恢复、ARCTIC生成队列收尾。 | 生成完成不代表两条历史GT缺口和辅助标签资格已解决。 |
365
+ | 354–355 | OakInk原生四元数与多物体适配。 | 不重新拟合手、生成衣物或恢复旧人体队列。 |
366
+ | 356 | 原NAS父预留覆盖子任务、容量预测和短序列回填;SSD896GiB总预算。 | 原source/render/camera/depth数值不变;不据此声称每条10分钟。 |
367
+
368
+ ### 独立样例与准备分支
369
+
370
+ | 分支 | 范围 | 边界 |
371
+ | --- | --- | --- |
372
+ | Hard Cases | 15条、10,838主源帧,全序列完整通道。 | 双手交叉来自公开真实动作;镜面为场景物理镜子、可带seed污渍;多人各自保留源时钟。镜面GT为首交点而非镜后虚像距离。 |
373
+ | 单目鱼眼 | 仅脚本准备:默认180°、1024方图、equidistant。 | 未全量部署;GT是ray distance而非pinhole camera-Z;无已资格噪声深度/DLSS,不纳入当前V006 complete索引。 |
374
+
375
+ ### 使用边界
376
+
377
+ - 渲染/深度完成、上游资产批准、辅助拟合齐全、逐帧质量验收和训练资格是不同状态;不合并成一个PASS。
378
+ - ARCTIC38条隐藏test GT不公开,不伪造;301公开动作覆盖不等于所有官方相机视角图像都重新渲染。
379
+ - 当前索引只数每源一份;train/val/test按原始source分组,历史变体和Hard Case不能导致同源泄漏。
380
+ - SSD/NAS和GPU优化不等于已达到十分钟端到端目标,吞吐比较应按源帧数和完整worker耗时。
381
+
382
+ - [实时进度](https://huggingface.co/datasets/DarthSoluke/EgoRendererStatus)
383
+ - [ARCTIC发布仓库](https://huggingface.co/datasets/DarthSoluke/EgoRenderer-V006-ARCTIC)
384
+ - [LingBot-Depth §3.1](https://arxiv.org/html/2601.17895v1#S3.SS1)
385
+
386
+ ## 证据索引
387
+
388
+ 以下为核查时原始文件的字节SHA256,只发布文件名和摘要,不公开内部路径、凭据或原始载荷。
389
+
390
+ V006初版合同的三变体及NAS-only计划已由后续明确单次生产、双深度和有界SSD修订覆盖;不得用旧合同恢复旧策略。
391
+
392
+ | 原始文件 | SHA256 |
393
+ | --- | --- |
394
+ | configs/egorenderer_ver_001.json | ea7ccacfb4e022cbc61a4ef1e71ecc33a7926a10bb4ec44d4691078b7817cf9e |
395
+ | configs/egorenderer_ver_002.json | 653cdbcda8b35ad5e0129ba2a907f18b10f176c201aaa38801c2d44793174450 |
396
+ | configs/egorenderer_ver_003.json | 6904142d98e365ad0df81afdc7252dd7baaf67a1dba3dffab2711d5b5fe81a28 |
397
+ | configs/egorenderer_ver_004.json | 87ec6cc68956c3c3b8ea6ba830d11b4d1fc3b7dc7d7d19949a411eae9d8cec88 |
398
+ | configs/egorenderer_ver_005.json | 3fc6b643829e9b0e50acb19706276881c16f713520498f07b9c628b148c4e6af |
399
+ | configs/egorenderer_ver_006.json | d6dbb052f0e4111122d883cfcdf6b42eba4498ab814f20b25efe43e3dbd98d8f |
400
+ | configs/egorenderer_v006_depth_policy.json | 3596c6c3af7471a6f11e437e37126b4d8c27bc27a8d2033317592c963d6dad8b |
401
+ | configs/egorenderer_ver_356_final_synthesis_depth.json | 399f976ecb5337f07c148963922473a0febfdaf6c8bca81c39cb07d7241b8474 |
402
+ | reports/hf_grab_ver005_audit_20261103/render_configuration_summary.json | 8e8c3711ba1a74923cf7db8e4976b8608a4056808ebc0eab2e18c7cb97756800 |
403
+ | reports/hf_grab_ver005_audit_20261103/sequence_levels.json | b2ce0e09972b628bd0a8af700ac980a0c19268d19b3d09a5635b9f2875051317 |
404
+ | reports/hf_grab_ver005_audit_20261103/mainline_source_catalog_to_hf_bindings.json | 772eff12feba8329bf2251c6e77ba39adb0cc72117ad0165613f4e944eb27572 |
405
+ | reports/hf_grab_ver005_audit_20261103/legacy_render_to_hf_bindings_corrected.json | 7776af388166968bc1e96943ac1b7625352dadb9e683003954dee6c55e757e8a |
406
+
index.html CHANGED
@@ -14,9 +14,9 @@
14
  <title>EgoNet Datasets</title>
15
  <link rel="icon" href="data:," />
16
  <link rel="stylesheet" href="src/styles.css" />
17
- <link rel="stylesheet" href="src/synthetic.css?v=oakink-production-20261102" />
18
  <script src="src/vendor/lucide.min.js" defer></script>
19
- <script type="module" src="src/app.js?v=oakink-production-20261102"></script>
20
  </head>
21
  <body>
22
  <a class="skip-link" href="#app">跳到内容</a>
 
14
  <title>EgoNet Datasets</title>
15
  <link rel="icon" href="data:," />
16
  <link rel="stylesheet" href="src/styles.css" />
17
+ <link rel="stylesheet" href="src/synthetic.css?v=history-20261103" />
18
  <script src="src/vendor/lucide.min.js" defer></script>
19
+ <script type="module" src="src/app.js?v=history-20261103"></script>
20
  </head>
21
  <body>
22
  <a class="skip-link" href="#app">跳到内容</a>
src/app.js CHANGED
@@ -8,7 +8,7 @@ import {
8
  bindDetail,
9
  } from "./catalog.js";
10
  import { methodsView, somaView, samplesView } from "./reference.js";
11
- import synthetic from "./synthetic.js?v=oakink-production-20261102";
12
 
13
  const app = document.getElementById("app");
14
  let context;
 
8
  bindDetail,
9
  } from "./catalog.js";
10
  import { methodsView, somaView, samplesView } from "./reference.js";
11
+ import synthetic from "./synthetic.js?v=history-20261103";
12
 
13
  const app = document.getElementById("app");
14
  let context;
src/page.html CHANGED
@@ -14,9 +14,9 @@
14
  <title>EgoNet Datasets</title>
15
  <link rel="icon" href="data:," />
16
  <link rel="stylesheet" href="src/styles.css" />
17
- <link rel="stylesheet" href="src/synthetic.css?v=oakink-production-20261102" />
18
  <script src="src/vendor/lucide.min.js" defer></script>
19
- <script type="module" src="src/app.js?v=oakink-production-20261102"></script>
20
  </head>
21
  <body>
22
  <a class="skip-link" href="#app">跳到内容</a>
 
14
  <title>EgoNet Datasets</title>
15
  <link rel="icon" href="data:," />
16
  <link rel="stylesheet" href="src/styles.css" />
17
+ <link rel="stylesheet" href="src/synthetic.css?v=history-20261103" />
18
  <script src="src/vendor/lucide.min.js" defer></script>
19
+ <script type="module" src="src/app.js?v=history-20261103"></script>
20
  </head>
21
  <body>
22
  <a class="skip-link" href="#app">跳到内容</a>
src/synthetic.css CHANGED
@@ -278,8 +278,11 @@
278
  border: 1px solid var(--line);
279
  border-radius: 4px;
280
  overflow: hidden;
 
 
 
281
  }
282
- .synth-version-picker button {
283
  border: 0;
284
  border-right: 1px solid var(--line);
285
  min-width: 66px;
@@ -288,11 +291,13 @@
288
  font: 13px var(--f-mono);
289
  color: var(--ink);
290
  background: var(--surface);
 
 
291
  }
292
- .synth-version-picker button:last-child {
293
  border-right: 0;
294
  }
295
- .synth-version-picker button[aria-pressed="true"] {
296
  background: var(--ink);
297
  color: var(--surface);
298
  }
@@ -301,6 +306,51 @@
301
  gap: 16px;
302
  min-height: 280px;
303
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  .synth-version-detail ul {
305
  padding-left: 20px;
306
  display: grid;
@@ -461,8 +511,9 @@
461
  }
462
  .synth-version-picker {
463
  width: 100%;
 
464
  }
465
- .synth-version-picker button {
466
  flex: 1;
467
  min-width: 44px;
468
  padding: 8px 5px;
@@ -470,6 +521,13 @@
470
  .synth-version-detail {
471
  min-height: 0;
472
  }
 
 
 
 
 
 
 
473
  .synth-head h1 {
474
  font-size: 24px;
475
  }
 
278
  border: 1px solid var(--line);
279
  border-radius: 4px;
280
  overflow: hidden;
281
+ position: sticky;
282
+ top: 0;
283
+ z-index: 3;
284
  }
285
+ .synth-version-picker a {
286
  border: 0;
287
  border-right: 1px solid var(--line);
288
  min-width: 66px;
 
291
  font: 13px var(--f-mono);
292
  color: var(--ink);
293
  background: var(--surface);
294
+ text-decoration: none;
295
+ text-align: center;
296
  }
297
+ .synth-version-picker a:last-child {
298
  border-right: 0;
299
  }
300
+ .synth-version-picker a[aria-current="page"] {
301
  background: var(--ink);
302
  color: var(--surface);
303
  }
 
306
  gap: 16px;
307
  min-height: 280px;
308
  }
309
+ .synth-version-heading {
310
+ display: flex;
311
+ align-items: baseline;
312
+ justify-content: space-between;
313
+ gap: 10px 20px;
314
+ flex-wrap: wrap;
315
+ }
316
+ .synth-version-heading > span {
317
+ font-size: 12px;
318
+ color: var(--muted);
319
+ }
320
+ .synth-version-delta {
321
+ max-width: 90ch;
322
+ font-size: 14px;
323
+ line-height: 1.9;
324
+ }
325
+ .synth-feature-section {
326
+ display: grid;
327
+ gap: 12px;
328
+ min-width: 0;
329
+ margin-top: 12px;
330
+ }
331
+ .synth-feature-section h3 {
332
+ font: 600 15px var(--f-body);
333
+ }
334
+ .synth-feature-section p {
335
+ font-size: 13px;
336
+ line-height: 1.9;
337
+ color: var(--muted);
338
+ }
339
+ .synth-version-table td:first-child {
340
+ width: 22%;
341
+ font-weight: 500;
342
+ }
343
+ .synth-version-overview td:first-child {
344
+ width: 62px;
345
+ white-space: nowrap;
346
+ font-family: var(--f-mono);
347
+ }
348
+ .synth-version-table td {
349
+ line-height: 1.85;
350
+ }
351
+ .synth-version-limits .synth-links {
352
+ margin-block: 16px 4px;
353
+ }
354
  .synth-version-detail ul {
355
  padding-left: 20px;
356
  display: grid;
 
511
  }
512
  .synth-version-picker {
513
  width: 100%;
514
+ top: 56px;
515
  }
516
+ .synth-version-picker a {
517
  flex: 1;
518
  min-width: 44px;
519
  padding: 8px 5px;
 
521
  .synth-version-detail {
522
  min-height: 0;
523
  }
524
+ .synth-facts-table table {
525
+ min-width: 0;
526
+ table-layout: fixed;
527
+ }
528
+ .synth-facts-table td:first-child {
529
+ width: 28%;
530
+ }
531
  .synth-head h1 {
532
  font-size: 24px;
533
  }
src/synthetic.js CHANGED
@@ -1,5 +1,7 @@
1
  import { esc, number, icon, enhance, table as sharedTable } from "./ui.js";
 
2
  let content,
 
3
  registry = [],
4
  snapshot,
5
  root,
@@ -233,12 +235,8 @@ function updateProgress() {
233
  ),
234
  );
235
  }
236
- function versionDetail() {
237
- const v = content.versions.find((x) => x.id === selectedVersion);
238
- return `<h2>V${v.id} · ${esc(v.title)}</h2><div class="synth-meta"><span>${esc(v.state)}</span><span>${esc(v.scope)}</span></div><ul>${v.features.map((f) => `<li>${esc(f)}</li>`).join("")}</ul><div class="synth-callout">${esc(v.read)}</div>`;
239
- }
240
- function versionsView() {
241
- return `<section class="synth-section"><h2>数据与方法版本</h2><div class="synth-version-picker" role="group" aria-label="版本">${content.versions.map((v) => `<button data-version="${v.id}" aria-pressed="${v.id === selectedVersion}">V${v.id}</button>`).join("")}</div><div id="synth-version-detail" class="synth-version-detail">${versionDetail()}</div></section>
242
  ${section(
243
  "V006关键执行修订",
244
  table(
@@ -337,7 +335,7 @@ function paint() {
337
  if (!root || !content) return;
338
  const body =
339
  tab() === "versions"
340
- ? versionsView()
341
  : tab() === "reading"
342
  ? readingView()
343
  : tab() === "samples"
@@ -354,13 +352,6 @@ function paint() {
354
  updateFreshness();
355
  updateProgress();
356
  };
357
- root.querySelectorAll("[data-version]").forEach(
358
- (b) =>
359
- (b.onclick = () => {
360
- selectedVersion = b.dataset.version;
361
- paint();
362
- }),
363
- );
364
  const filter = root.querySelector("#synth-job-filter");
365
  if (filter)
366
  filter.onchange = () => {
@@ -433,15 +424,17 @@ function unmount() {
433
  }
434
  async function mount() {
435
  root = document.getElementById("synthetic-root");
 
436
  const own = generation;
437
  try {
438
  if (!content) {
439
  const responses = await Promise.all(
440
- ["egorender", "egorender-registry", "egorender-progress"].map((n) =>
441
  fetch("data/" + n + ".json"),
442
  ),
443
  );
444
- if (!responses[0].ok) throw new Error("content");
 
445
  content = await responses[0].json();
446
  registry = responses[1].ok ? await responses[1].json() : [];
447
  const cached = responses[2].ok ? await responses[2].json() : null;
 
1
  import { esc, number, icon, enhance, table as sharedTable } from "./ui.js";
2
+ import { versionsView, versionFromHash } from "./versions.js?v=history-20261103";
3
  let content,
4
+ versionHistory,
5
  registry = [],
6
  snapshot,
7
  root,
 
235
  ),
236
  );
237
  }
238
+ function versionPage() {
239
+ return `${versionsView(content, versionHistory, selectedVersion)}
 
 
 
 
240
  ${section(
241
  "V006关键执行修订",
242
  table(
 
335
  if (!root || !content) return;
336
  const body =
337
  tab() === "versions"
338
+ ? versionPage()
339
  : tab() === "reading"
340
  ? readingView()
341
  : tab() === "samples"
 
352
  updateFreshness();
353
  updateProgress();
354
  };
 
 
 
 
 
 
 
355
  const filter = root.querySelector("#synth-job-filter");
356
  if (filter)
357
  filter.onchange = () => {
 
424
  }
425
  async function mount() {
426
  root = document.getElementById("synthetic-root");
427
+ selectedVersion = versionFromHash(location.hash);
428
  const own = generation;
429
  try {
430
  if (!content) {
431
  const responses = await Promise.all(
432
+ ["egorender", "egorender-registry", "egorender-progress", "egorender-versions"].map((n) =>
433
  fetch("data/" + n + ".json"),
434
  ),
435
  );
436
+ if (!responses[0].ok || !responses[3].ok) throw new Error("content");
437
+ versionHistory = await responses[3].json();
438
  content = await responses[0].json();
439
  registry = responses[1].ok ? await responses[1].json() : [];
440
  const cached = responses[2].ok ? await responses[2].json() : null;
src/versions.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { esc, table } from "./ui.js";
2
+
3
+ export function versionFromHash(hash) {
4
+ const id = hash.split("/")[2];
5
+ return /^(001|002|003|004|005|006)$/.test(id) ? id : "006";
6
+ }
7
+
8
+ function rows(headers, values, className = "") {
9
+ return table(
10
+ headers,
11
+ values.map((row) => `<tr>${row.map((v) => `<td>${esc(v)}</td>`).join("")}</tr>`),
12
+ "synth-table synth-version-table " + (headers.length === 2 ? "synth-facts-table " : "") + className,
13
+ );
14
+ }
15
+
16
+ export function versionDetail(version, history) {
17
+ const detail = history.versions.find((v) => v.id === version.id);
18
+ return `<header class="synth-version-heading"><h2>V${esc(version.id)} · ${esc(version.title)}</h2><span>${esc(version.state)}</span></header>
19
+ <p class="synth-version-delta">${esc(detail.delta)}</p>
20
+ ${detail.groups.map((group) => `<section class="synth-feature-section"><h3>${esc(group.title)}</h3>${rows(group.headers, group.rows)}${(group.notes || []).map((note) => `<p>${esc(note)}</p>`).join("")}</section>`).join("")}
21
+ <details class="synth-version-limits"><summary>使用边界与来源</summary><ul>${detail.limits.map((text) => `<li>${esc(text)}</li>`).join("")}</ul>${detail.references?.length ? `<div class="synth-links">${detail.references.map(([title, url]) => `<a href="${esc(url)}" target="_blank" rel="noopener noreferrer">${esc(title)}</a>`).join("")}</div>` : ""}</details>`;
22
+ }
23
+
24
+ export function versionsView(content, history, selected) {
25
+ const version = content.versions.find((v) => v.id === selected);
26
+ return `<section class="synth-section"><div class="synth-toolbar"><h2>版本对照</h2><div class="synth-links"><a href="downloads/egorender_versions.md" download>Markdown</a><a href="data/egorender-versions.json" download>JSON</a></div></div>
27
+ ${rows(["版本", "改变什么", "RGB", "深度", "覆盖与边界"], history.comparison, "synth-version-overview")}
28
+ <details><summary>数据版本、渲染批次、执行修订</summary>${rows(["层级", "例子", "含义"], history.naming)}</details></section>
29
+ <section class="synth-section"><nav class="synth-version-picker" aria-label="版本">${content.versions.map((v) => `<a href="#synthetic/versions/${esc(v.id)}" data-version="${esc(v.id)}" ${v.id === selected ? 'aria-current="page"' : ""}>V${esc(v.id)}</a>`).join("")}</nav>
30
+ <article id="synth-version-detail" class="synth-version-detail">${versionDetail(version, history)}</article></section>`;
31
+ }