geopro/.superpowers/sdd/task-12d-report.md

174 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Task 12d 收尾探针报告 —— 视觉调优 + fps 预算 + 可交互开窗
实测环境: 本机 RTX 3060 / VTK 9.6 / MSVC+Ninja。store: `tmp/store_lod_001`
(level0 = 44476×29×162, 4 层金字塔, brick=64, 2.09 亿体素)。
所有数字为真实离屏实测, 双闸(纹理错捕获 + 回读非空像素)防假帧率。
---
## 状态
完成。三件事全部落地、编译通过、离屏实测出数:
-`tune` 视觉调优: 出 `lod-tuned-local.png` / `lod-tuned-overview.png`, 打印调优前后 fps 对照。
-`fps-budget`: 递增全分辨率窗口 fps 表 + 每帧体素预算结论。
-`view`: 真窗口 + interactor + 缩放切 LOD + 屏幕 fps 文本; 离屏 `--smoke` 通过不崩。
改动文件: `tools/gpr_poc/main.cpp` (新增 3 个子命令 + 视觉调优共享构件), 新增两张调优截图,
追加写 `docs/superpowers/plans/poc-results-C.md`
---
## ① 视觉调优: 调优前后 fps 对照(证实视觉调优 fps 近乎中性)
`gpr_poc tune <store> --opacity 0.7 --exagg 8 --localBricks 4` (level0 256×29×162 局部段):
| 配置 | 色阶 | 不透明度 | 垂向夸张 | 局部 fps |
|---|---|---|---|---|
| 调优前(基线) | 蓝-白-红线性单斜坡 | 0.15 | 1× | 323.3 |
| 调优后 | 结构色阶(深蓝→青→白→黄→红) + 双端斜坡 | 0.7 | 8× | 349.2 |
**fps 变化 = 8.0%(即调优后反而更快)**。完全证实探针认知:
- 隔离实验(`--exagg 1`): 不透明度 0.15→0.5/0.6、换结构色阶, fps 5.5%(更快)。
**配色/不透明度对 fps 近乎中性, 调高不透明度甚至更快(光线提前终止)。**
- 隔离实验(`--opacity 0.9 --exagg 10`): fps 反而 +49%(更快)。
双端斜坡把占多数的近零背景设透明, 不透明片段少 + 提前终止, 抵消了夸张放大的屏占。
- 早先一版"线性单斜坡 + exagg 8"曾掉 34%, 经排查 **掉帧全部来自垂向夸张(8× 放大薄轴
→ 屏占变大 → ray-cast 片段变多), 与不透明度/配色无关**。改用双端斜坡(背景透明)后
即转为净加速。
**关键视觉修复**: GPR/地震体值集中在零附近(背景), 强反射在正负两端。原线性单斜坡让
近零背景填满体、遮住结构(实测渲出一块均匀蓝板, 无结构)。改为**双端斜坡(中段透明 +
正负两端不透明)** 后, 截面的层状反射(地层条带)清晰可辨。
调优截图:
- `docs/superpowers/plans/poc-lod-shots/lod-tuned-local.png`
—— 全分辨率局部段, 可见多条水平层状反射条带(地层结构)+ 一处相干蓝色异常体。
- `docs/superpowers/plans/poc-lod-shots/lod-tuned-overview.png`
—— 粗层(level2)概览。物理真实: 整线 2.2km×1.5m×8m 极扁, 概览就是一条细带(可接受)。
> 诚实说明: 体物理纵横比极端(X≈2.2km vs Y≈1.5m / Z≈8m), 即便取局部段 + 8× 夸张,
> 单帧里结构仍偏小、偏一隅, 背景大片黑。结构确实可辨(层状条带 + 异常体), 但"一眼炸裂"
> 受物理形态限制——这正是 brief 预期的"细带本质"。production 可配可调色阶/取景控件让
> 用户交互找最佳视角(即 ③ view)。
---
## ② fps 预算: 递增全分辨率(level0)窗口 → 每帧体素预算
`gpr_poc fps-budget <store> --bricks 4,16,64,128,256,512,695 --frames 90`
(沿线中段递增 brick 列, 单 image 整段体绘制, 双闸):
| brick 段 | 维度 | 体素数 | 体绘制 fps | ≥30 | 备注 |
|---|---|---|---|---|---|
| 4 | 256×29×162 | 1,202,688 | 218.3 | 是 | |
| 16 | 1024×29×162 | 4,810,752 | 155.7 | 是 | |
| 64 | 4096×29×162 | 19,243,008 | 240.9 | 是 | |
| 128 | 8192×29×162 | 38,486,016 | 305.8 | 是 | |
| 256 | 16384×29×162 | 76,972,032 | 329.7 | 是 | 触达 GL_MAX_3D_TEXTURE_SIZE=16384 |
| 512 | 32768×29×162 | 153,944,064 | INVALID | 否 | X=32768>16384, 纹理墙, 双闸标 INVALID |
| 695 | 44476×29×162 | 208,948,248 | INVALID | 否 | 同上 |
### 每帧体素预算结论(重要, 与 brief 框架略有出入但更真实)
- **fps 在所有可上传测点(≤16384 单轴)始终 ≫ 30(218~330fps), 全程没跌破 30。** fps 不随
体素数单调下降(甚至上升), 因 ray-cast 成本主要由屏占 × 采样步长决定, 而薄维度(Y29/Z162)
使光线路径短, 单 3D 纹理上传成功后体素总数不是瓶颈。
- **真正的硬墙是 GL_MAX_3D_TEXTURE_SIZE = 16384**: 单轴超 16384 → 整段无法成单张 3D 纹理
(512/695 行双闸正确判 INVALID, 绝不当真上报)。
- 因此本数据集上, **"单张 3D 纹理的每帧体素预算" = 单轴 ≤16384 → ≈ 7700 万体素(256 brick 列)**
跑 ~330fps 仍极宽裕; **限制 production LOD 每帧块数的不是 30fps 阈值, 而是 16384 纹理墙——
超墙必须切块(MultiBlock / SetPartitions / 本机核外 OutOfCoreSource)。**
- fps 驱动的体素预算(跌破 30)只会在远更大/更稠密体或多块叠加渲染时出现; 本数据集薄维度下
GPU 余量充足, 未触达。
> 这与 brief"找 fps<30 阈值"的设想不同, 但是实测真相: **本数据集的命门是纹理尺寸墙,
> 不是帧率墙**。如实记录。
---
## ③ `gpr_poc view <store>` —— 真窗口可交互(给用户肉眼测 + 最低配机跑)
实现要点:
-`vtkRenderWindow` + `vtkRenderWindowInteractor`(`vtkInteractorStyleTrackballCamera`),
`OutOfCoreSource`(核外 LOD + 视野选块, budget 限驻留, 内存恒定)。
- 相机变化(`EndInteractionEvent`)→ `source.update(camera)` 重选 LOD/视野块 → 重建 MultiBlock
→ 重渲。**缩放跨越距离/对角线档位时 LOD 真切换**(离屏 smoke 实测 level 1↔0 切换)。
- 屏幕左上角 `vtkTextActor` 实时显示 `fps | LOD level | blocks | exagg`, 每帧更新。
- 默认结构色阶 + 双端斜坡不透明度 + 垂向夸张(同 ①)。
- 参数: `--exagg N --opacity F --budget K`(K=每帧最大全分辨率块数, 接 ② 预算)。
离屏 smoke(`view --smoke`)实测:
```
预热: level=1 视野块=696/696 驻留=64 渲染块=64
近观 level=1 → 拉远 level=1 → 再拉近 level=0
LOD 随缩放切换 : 是 ✔
纹理维度错误 : 否
渲出非空像素 : 是 (近=1024000 远拉近=1024000)
smoke 结果 : OK ✔ 不崩
```
### view 命令用法
```
gpr_poc view <storeDir> [--exagg 8] [--opacity 0.6] [--budget 64] [--smoke]
```
- 不带 `--smoke` = 开真窗口可交互(留给用户跑)。
-`--smoke` = 离屏建管线 + 模拟缩放验 LOD 切换 + 验不崩(CI/无显示环境用)。
---
## 给用户的肉眼测试说明(请转达用户)
**启动命令**(在已构建的仓库根目录):
```
build\release\tools\gpr_poc\gpr_poc.exe view tmp\store_lod_001 --exagg 8 --opacity 0.6 --budget 64
```
- DLL/PATH: 无需手设。CMake 已把 VTK/Qt 等运行时 DLL 拷到 exe 旁(`gpr_poc.exe` 同目录),
直接双击/命令行运行即可。
- 若换其它 store, 把 `tmp\store_lod_001` 换成你的金字塔 store 目录(需先 `gpr_poc build ... --levels 3`)。
**操作:**
- **滚轮**: 向前滚拉近 → 应看到全分辨率结构(屏幕 `LOD level` 数字变小, 0=最细);
向后滚拉远 → 变粗层概览(level 数字变大, 体变糊)。
- **左键拖动**: 旋转视角(TrackballCamera)。
- **q 键 / 关窗**: 退出。
**判断点(可接受标准):**
1. **拉近后能否看清地质结构**: 局部段应呈现水平层状反射条带(地层)+ 可辨的相干异常体。
能看出层次即可接受(受物理细带形态限制, 不会像规则立方体那样饱满)。
2. **概览(细带)可不可接受**: 拉远后是一条细长带(整线 2.2km×1.5m×8m 物理真实), 接受它是细带。
3. **拉近/拉远切 LOD 时卡不卡、糊→清过渡能不能接受**: 切换应顺滑, 无明显卡死/长 stall
(本机切换 ~5-9ms, 远小于 1 个 60Hz 帧 16.7ms, 不可感)。
4. **屏幕 fps 是否 ≥30**: 屏幕左上角实时 fps。本机(RTX 3060)远超 30(数百 fps);
**最低配机重点看这条**——拉到最细 LOD、最大夸张时 fps 是否仍 ≥30。
**最低配怎么跑:**
- 把整个 `build\release\tools\gpr_poc\` 目录(含所有 DLL)+ 一个 store 目录拷到目标机,
跑上面的 `view` 命令, 肉眼看屏幕 fps 与交互流畅度。
- 或无显示/批处理场景跑 `gpr_poc fps-budget tmp\store_lod_001` 出该机的体素-fps 表对照。
---
## 最低配未验声明
本探针仅在本机 **RTX 3060** 跑出上限数字(数百 fps, 余量充足)。**最低配机器未验证**,
需用户拿目标机跑 `gpr_poc view <store>`(肉眼判 fps≥30 + 交互流畅)或 `gpr_poc fps-budget <store>`
(出该机体素-fps 表)。production 是否对最低配可用, 以目标机实测为准。
---
## Concerns
1. **视觉天花板受物理形态限制**: 体极扁(2.2km×1.5m×8m), 单帧结构偏小偏一隅。这是数据物理
真实, 非 bug; production 应给用户交互色阶/取景/裁剪控件(view 已具备旋转缩放, 色阶可参数化)。
2. **fps 不是本数据集的瓶颈, 纹理尺寸墙(16384)才是**: 与 brief"找 fps<30 阈值"设想不同
每帧体素预算结论是"单轴 16384 即可单纹理上传, fps 30", 超墙必须切块如实记录
3. **view 的 LOD 阈值按未夸张几何标定**: `pickLevel` level0 原始对角线算距离比, actor
`SetScale(1,exagg,exagg)`夸张会轻微平移"缩放-LOD 映射"档位, 但切换仍正常触发
(smoke 实测 level 10)。若用户觉得切档时机别扭, 后续可让 pickLevel 感知夸张系数
4. **view 连续拖动 fps 文本基于上一帧耗时估算**(单帧 wall-clock 倒数), 非滑动平均, 数字会抖;
足够给用户感知量级(几十/几百 fps), 非精密基准(精密基准走 fps-budget/renderLOD 离屏)。
5. `last-metrics.txt`(repo , 探针追加输出)未纳入提交——它从未被 git 跟踪, 是瞬时产物