《江格尔》十二英雄——基于手写 WebGL 管线的史诗数字展陈交互系统TECHNICAL CONSOLE · BUILD 2026-11-30

软件作品 · 技术控制台 · 指定命题「民族文化 创新表达」

把 70–117 MB 一尊的三维资产,
压到能在手机里真实旋转。

《江格尔》史诗非遗数字化采集产出的原始三维资产,单尊 150 万三角面、 单模型 70–117 MB。而它真正需要触达的阵地是手机浏览器与微信—— 弱网、低端设备、以及微信小程序 1.5 MB 的主包上限。

本系统是解决这一矛盾的构建期处理管线与运行时跨端渲染引擎: 配置驱动,外部库 0 个、Draco 解码器 0 个、CDN 依赖 0 个。

这一页的所有数字都是构建期从 GLB 二进制里量出来的,不是手写的。 运行 node scripts/assetctl.mjs all 可完整复现本页全部指标—— 这是本作品"可验证性"的实现方式。

处理结果

原始资产 → 产出资产的全量对比。所有数值由 assetctl 直接解析 GLB 容器得出。

原始资产合计
930.22MiB
12 尊,单尊 73–88 MB
精细版合计
53.74MiB
压缩至原始 5.8%
精细版 gzip 传输
36.01MiB
再降 67.0%
轻量版单尊均值
619KiB
首屏即可旋转
三角面保留
7.0%
产出 2,532,157 / 原始 35,994,240
每顶点字节
13B
位置 6 + 法线 3 + UV 4
外部运行时依赖
0
无 Three.js / 无 Draco / 无 CDN
平均 ACMR
1.159
32 槽顶点缓存(u16 预检 1.365)
预算断言
全部通过
含 manifest 与实际资产一致性

软件架构

四层分离:构建期管线只读解析容器、产出双级资产与清单;运行时引擎只负责解压与绘制; 应用层承载展馆、图谱与 AI 叙述;数据层用单一数据源保证双端一致。 层与层之间以文件契约(manifest / 数据集 JSON)耦合,因此管线可脱离本项目复用。

BUILD TIME 构建期 RUN TIME 运行时 DATA 数据层 原始采集资产 models2/ · 单尊 70–117 MB 只读容器解析 JSON chunk + bufferViews ① 资产处理管线 assetctl.mjs 量化 · 紧凑化 · 双级产出 预算断言 · 量化报告 轻量版 preview u16 索引 · 首屏可旋转 精细版 detail u32 索引 · 完整精度 清单与报告 manifest.json asset-report.json 内容哈希命名 ② 跨端渲染引擎 GLB 解析 · WebGL 管线 KHR_mesh_quantization 展开 渐进式替换保状态 无 Three.js · 无 Draco Web 端 浏览器 / WebGL 1+2 微信小程序端 主包 ≤1.5 MB ③ 应用层 数字展馆 · 英雄图鉴 知识图谱 · 史料溯源 ④ AI 辅助叙述 检索增强 · 语音播报 英雄名录单一数据源 src/heroes.6b32633f9321.js 与小程序端构建期同步 check-roster 断言一致性 知识图谱数据集 jangar-graph.json 异名 · 篇章 · 师承 check-graph 校验引用完整性 史料溯源台账 provenance.json 来源 / 采集 / 核对状态 缺来源的字段显式标 null

PREVIEW

轻量版

首屏即可旋转的版本。移动端/弱网/2G 模式默认只加载这一级,用户可手动请求精细版。

  • 资产数:12
  • 传输上限:750 KiB/个,实测均 gzip 542 KiB
  • 索引类型:u16

DETAIL

精细版

完整精度版本。轻量版就绪后后台流式替换,替换过程保持用户当前角度/缩放/自动旋转状态。

  • 资产数:12
  • 传输上限:6 MiB/个,实测均 gzip 3073 KiB
  • 原始体积上限:10 MiB/个,实测均 4586 KiB
  • 索引类型:u32

CONTRACT

级间契约

管线不直接调用渲染代码,只产出文件:双级 GLB + manifest.json。 渲染引擎不关心资产怎么来的,只读清单。

  • 替换资产来源:改 assetctl.config.json
  • 替换渲染目标:实现同一清单读取契约
  • 契约变更可被预算断言与校验脚本拦截

资产清单

24 个产出资产。几何与贴图字节数分开统计——这个拆分决定了优化该往哪使劲: 本批资产几何占比 80.6%,因此减面与顶点紧凑化是主要收益来源, 而不是一味压贴图。

资产原始gzip几何贴图 顶点三角面索引字节/顶点量化
alatancheji轻量版 738 KiB 647 KiB 525 KiB 211 KiB 27,726 29,543 u16 13 是
guzangongbu轻量版 659 KiB 580 KiB 484 KiB 173 KiB 25,263 27,937 u16 13 是
harijilagen轻量版 561 KiB 494 KiB 421 KiB 138 KiB 21,880 24,509 u16 13 是
harinidun轻量版 639 KiB 554 KiB 492 KiB 145 KiB 26,397 26,828 u16 13 是
hejilagen轻量版 635 KiB 559 KiB 497 KiB 137 KiB 24,764 31,111 u16 13 是
hongguer轻量版 761 KiB 662 KiB 606 KiB 154 KiB 31,443 35,248 u16 13 是
jiangger轻量版 580 KiB 519 KiB 383 KiB 195 KiB 19,714 22,617 u16 13 是
mingyan轻量版 579 KiB 511 KiB 414 KiB 163 KiB 21,420 24,224 u16 13 是
naqinshanghuer轻量版 571 KiB 504 KiB 387 KiB 183 KiB 20,271 22,129 u16 13 是
saber轻量版 633 KiB 546 KiB 517 KiB 114 KiB 27,280 29,123 u16 13 是
sailihantabage轻量版 516 KiB 450 KiB 415 KiB 100 KiB 21,141 24,958 u16 13 是
sanala轻量版 557 KiB 485 KiB 429 KiB 127 KiB 22,663 24,051 u16 13 是
alatancheji精细版 5020 KiB 3409 KiB 3982 KiB 1036 KiB 135,248 193,270 u32 13 是
guzangongbu精细版 4564 KiB 3071 KiB 3708 KiB 854 KiB 123,440 182,718 u32 13 是
harijilagen精细版 3936 KiB 2615 KiB 3259 KiB 675 KiB 107,787 161,366 u32 13 是
harinidun精细版 4378 KiB 2918 KiB 3668 KiB 708 KiB 125,537 177,026 u32 13 是
hejilagen精细版 4655 KiB 3012 KiB 3980 KiB 673 KiB 126,827 202,248 u32 13 是
hongguer精细版 5348 KiB 3502 KiB 4541 KiB 806 KiB 149,678 225,313 u32 13 是
jiangger精细版 7000 KiB 4943 KiB 4996 KiB 2002 KiB 160,256 252,732 u32 13 是
mingyan精细版 4069 KiB 2758 KiB 3240 KiB 827 KiB 108,307 159,137 u32 13 是
naqinshanghuer精细版 3920 KiB 2701 KiB 3014 KiB 905 KiB 102,226 146,452 u32 13 是
saber精细版 4437 KiB 2877 KiB 3863 KiB 573 KiB 129,978 188,805 u32 13 是
sailihantabage精细版 3771 KiB 2436 KiB 3277 KiB 492 KiB 107,032 163,706 u32 13 是
sanala精细版 3934 KiB 2629 KiB 3244 KiB 689 KiB 110,469 157,106 u32 13 是

合计 24 个资产:原始 61.00 MiB → gzip 42.36 MiB (压缩 30.5%);几何 49.16 MiB / 贴图 11.80 MiB;GPU 贴图常驻(含 mipmap)290.00 MiB。

顶点缓存效率(ACMR)

ACMR(Average Cache Miss Ratio)是 GPU 后变换缓存命中率的行业指标,1.0 为理想值。 本项检查用于回答一个具体工程问题:轻量版能退回 16 位索引吗? 16 位索引可再省一半索引字节,但顶点复用率不足时反而拖慢绘制。 实测 u16 预检值整体升高至 1.365,因此轻量版保留 u16(体积优先,因该级受 750 KiB 硬约束), 精细版保留 u32(绘制效率优先)。

级别模型顶点三角面索引复用比 ACMR32ACMR16
previewalatancheji 27,72629,543 3.21.2061.367
previewguzangongbu 25,26327,937 3.321.1731.354
previewharijilagen 21,88024,509 3.361.1561.33
previewharinidun 26,39726,828 3.051.2561.434
previewhejilagen 24,76431,111 3.771.0791.232
previewhongguer 31,44335,248 3.361.1831.386
previewjiangger 19,71422,617 3.441.1331.29
previewmingyan 21,42024,224 3.391.1481.308
previewnaqinshanghuer 20,27122,129 3.271.1741.343
previewsaber 27,28029,123 3.21.2011.368
previewsailihantabage 21,14124,958 3.541.1011.268
previewsanala 22,66324,051 3.181.1931.354
detailalatancheji 135,248193,270 4.291.1711.408
detailguzangongbu 123,440182,718 4.441.1621.404
detailharijilagen 107,787161,366 4.491.131.381
detailharinidun 125,537177,026 4.231.221.493
detailhejilagen 126,827202,248 4.781.0731.302
detailhongguer 149,678225,313 4.521.1681.43
detailjiangger 160,256252,732 4.731.1491.383
detailmingyan 108,307159,137 4.411.1361.365
detailnaqinshanghuer 102,226146,452 4.31.1841.425
detailsaber 129,978188,805 4.361.1531.393
detailsailihantabage 107,032163,706 4.591.1191.364
detailsanala 110,469157,106 4.271.1491.386

平均 ACMR32 1.159 / ACMR16 1.365。 以 FIFO 顶点缓存简化模型估算,仅用于同一批资产内部横向比较,不代表真实驱动绝对值。

命令行接口

一条命令复现本页全部数字。管线是独立的命令行工具,不依赖本项目其余代码。

# 全量:解析资产 → 校验预算 → 顶点缓存分析 → 写出 JSON/Markdown 报告
  node scripts/assetctl.mjs all

  # 单独跑某一项
  node scripts/assetctl.mjs verify      # 仅校验预算与完整性(CI 门禁用,失败退出码 1)
  node scripts/assetctl.mjs report      # 仅生成逐资产量化报告
  node scripts/assetctl.mjs cache       # 仅做顶点缓存效率分析

  # 限定级别 / 指定输出目录
  node scripts/assetctl.mjs report --tier=preview --out=reports/preview

  # 产物
  #   reports/asset-report.json   机器可读,供 CI 与页面消费
  #   reports/asset-report.md     人可读,可直接附入参赛材料
  #   public/console.html          本页(由 gen-console.mjs 读报告生成)

DESIGN CHOICE

为什么自己解析 GLB 而不用现成库

不是重复造轮子,是约束条件决定的。

  • 微信小程序主包上限 1.5 MB,不允许下载外部解码器
  • 图形管线自研;网页动效使用本地 Anime.js,无 CDN 依赖
  • 自研换来的是:完全可控的加载策略、体积预算与失败降级路径

DESIGN CHOICE

为什么不用 Draco 而用量化

Draco 压缩率更高,但需要附带第三方解码器代码(体积与许可双重成本)。

  • 改用 glTF 官方扩展 KHR_mesh_quantization
  • 顶点属性紧凑存储:位置 6 B / 法线 3 B / UV 4 B,合计 13 B/顶点
  • 解压由自研运行时完成,零第三方代码

REUSABILITY

换一批资产怎么用

管线与"江格尔"这一具体内容解耦,只依赖配置文件。

  • 改 assetctl.config.json 的 tiers 与预算
  • 指向新的资产目录,重新运行 assetctl all
  • 预算断言与报告自动适配新资产

运行时约束与预算断言

作品运行环境的硬约束在这里逐条列出,并由 assetctl verify 在构建期断言。 约束不是描述,是门禁:违反即构建失败。

RUNTIME

零外部依赖

  • 外部库:无
  • Draco 解码器:不需要
  • Three.js:不使用
  • CDN 依赖:无

BUDGETS

体积预算(两个指标,不能混用)

  • 传输体积(gzip)决定用户实际下载量与缓存占用: 轻量 ≤ 750 KiB/个、 精细 ≤ 6 MiB/个、 精细合计 ≤ 80 MiB
  • 原始体积(GLB)只受部署平台单文件上限约束: 精细 ≤ 10 MiB/个、 平台硬限 25 MiB
  • 小程序主包 ≤ 1.5 MB
  • 拿 gzip 当磁盘体积会低估,拿原始体积当传输体积会高估

PERFORMANCE

性能预算

  • 首次可交互 ≤ 2000 ms
  • 精细版就绪 ≤ 8000 ms
  • 测试条件:5 Mbps 下行 / 100 ms 延迟 / 冷缓存
  • 离屏或静止时减少渲染,降低移动端耗电

构建期断言结果