174 lines
9.6 KiB
Markdown
174 lines
9.6 KiB
Markdown
# 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 1↔0)。若用户觉得切档时机别扭, 后续可让 pickLevel 感知夸张系数。
|
||
4. **view 连续拖动 fps 文本基于上一帧耗时估算**(单帧 wall-clock 倒数), 非滑动平均, 数字会抖;
|
||
足够给用户感知量级(几十/几百 fps), 非精密基准(精密基准走 fps-budget/renderLOD 离屏)。
|
||
5. `last-metrics.txt`(repo 根, 探针追加输出)未纳入提交——它从未被 git 跟踪, 是瞬时产物。
|