From f52d38d97b0c1127b772259a82a3275825eeb97e Mon Sep 17 00:00:00 2001 From: gaozheng Date: Thu, 25 Jun 2026 15:20:14 +0800 Subject: [PATCH] =?UTF-8?q?perf(gpr=5Fpoc):=20view-all=20=E6=A6=82?= =?UTF-8?q?=E8=A7=88=E6=AF=8F=E7=BA=BF=E5=8D=95=E4=BD=93=20LOD,40=20?= =?UTF-8?q?=E4=BD=93=E2=86=9220=20=E4=BD=93=E4=BF=AE=201fps=20=E5=8D=A1?= =?UTF-8?q?=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit P11 cmdViewAll 每条线把 baseVolume(常驻底图)+hiresVolume(高清)两层都加进 renderer,20 线=40 体每帧 ray-cast,概览全可见(culled 0)→1.1fps。 改为每线只渲一个体:起步喂 baseImage()(粗 whole,小且不空,≤16384),引擎 按相机备好更合适 LOD 单图(currentImages)后整图换上 → 任何时刻每线 ≤1 体, 最多 20 体。视锥裁剪 toggle 唯一体可见性,拖动降采样保留,静止只渲就绪纹理 不重建。复用 ViewAdaptiveVolumeSource 引擎,未改库。 概览 1.1fps→42.98fps;体数 40→20(20 visible/0 culled);拉近 22.85fps (17 visible/3 culled,视锥裁剪生效);无纹理维度错误,满帧非空白。 --- tools/gpr_poc/main.cpp | 77 ++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/tools/gpr_poc/main.cpp b/tools/gpr_poc/main.cpp index d2dcad7..2dcd9fd 100644 --- a/tools/gpr_poc/main.cpp +++ b/tools/gpr_poc/main.cpp @@ -4002,12 +4002,13 @@ struct PlacedSource { vtkSmartPointer world; // T:Scale(1,1,exagg)→RotateZ→Translate vtkSmartPointer worldInv; // T⁻¹(相机逆变换到局部帧) - vtkSmartPointer prop; // 逐线 2/98 分位标定的传函(底图+高清共用) - vtkSmartPointer baseVolume; // 常驻粗底图(永在场,套 T) - vtkSmartPointer baseMapper; - vtkSmartPointer hiresVolume; // 高清叠加(就绪后局部覆盖,套 T) - vtkSmartPointer hiresMapper; - vtkSmartPointer currentImg; // 持当前高清单图引用(mapper 仅持裸指针) + vtkSmartPointer prop; // 逐线 2/98 分位标定的传函 + // P12:每线只渲【一个】体(不再底图层 + 高清层叠双渲,20 线=40 体爆 1fps)。 + // 该体输入由引擎按相机选的 LOD 决定:起步喂 baseImage()(粗 whole,小且不空), + // 引擎备好更合适的 currentImages() 后整图换上 → 任何时刻每线 ≤1 体 → 最多 20 体。 + vtkSmartPointer volume; // 唯一体(套 T) + vtkSmartPointer mapper; + vtkSmartPointer currentImg; // 持当前单图引用(mapper 仅持裸指针) double worldBounds[6] = {0, 0, 0, 0, 0, 0}; // 该线(含 T+底图盒)的世界 AABB(视锥裁剪用) bool culled = false; // 本帧是否被视锥裁掉(两层皆隐 → 真跳过) @@ -4082,17 +4083,16 @@ void viewAllSubmitOneLine(PlacedSource& ps, vtkCamera* worldCam, 1.0}); } -// 非阻塞拉取该线后台已就绪的高清单图,喂高清 mapper(无新结果→沿用上一帧)。 -// 返回 1=换上新图。 +// 非阻塞拉取该线后台已就绪的引擎单图,换上唯一体的 mapper(无新结果→沿用上一帧)。 +// 返回 1=换上新图。P12:单体单层,引擎选 LOD(远→粗 whole,近→细局部)。 int viewAllPickOneLine(PlacedSource& ps) { if (ps.culled) return 0; auto imgs = ps.source->currentImages(); // 内部 takeLatest(非阻塞) if (imgs.empty() || imgs[0] == nullptr) return 0; if (imgs[0] == ps.currentImg) return 0; ps.currentImg = imgs[0]; - ps.hiresMapper->SetInputData(ps.currentImg); - ps.hiresMapper->Update(); - ps.hiresVolume->SetVisibility(1); + ps.mapper->SetInputData(ps.currentImg); + ps.mapper->Update(); return 1; } @@ -4134,14 +4134,9 @@ void viewAllRefreshFrustum(ViewAllState* st) { for (PlacedSource& ps : *st->lines) { const bool outside = aabbOutsideFrustum(ps.worldBounds, planes); ps.culled = outside; - ps.baseVolume->SetVisibility(outside ? 0 : 1); - if (outside) { - ps.hiresVolume->SetVisibility(0); - } else { - // 可见:提交引擎目标(局部帧),高清可见性由 pick 决定(有就绪图才显)。 - viewAllSubmitOneLine(ps, st->cam, st->aspect, st->viewportH); - ps.hiresVolume->SetVisibility(ps.currentImg != nullptr ? 1 : 0); - } + // P12:每线唯一体。视锥外→隐(真跳过 ray-cast);可见→显并提交引擎目标(局部帧)。 + ps.volume->SetVisibility(outside ? 0 : 1); + if (!outside) viewAllSubmitOneLine(ps, st->cam, st->aspect, st->viewportH); } } @@ -4363,32 +4358,24 @@ int cmdViewAll(int argc, char** argv) { ps.worldInv->DeepCopy(ps.world); ps.worldInv->Inverse(); - // 逐线传函(从常驻底图标定)+ 底图层 + 高清层,两层皆套世界变换 T。 + // 逐线传函(从常驻底图标定)。P12:每线只建【一个】体(套世界变换 T), + // 起步喂粗底图(小且不空),引擎备好更合适 LOD 单图后整图换上。 ps.prop = buildLineProperty(ps.meta, ps.source->baseImage()); - ps.baseMapper = vtkSmartPointer::New(); - ps.baseMapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode); - ps.baseMapper->SetAutoAdjustSampleDistances(1); - ps.baseMapper->SetInteractiveAdjustSampleDistances(1); - ps.baseVolume = vtkSmartPointer::New(); - if (ps.source->baseImage() != nullptr) { - ps.baseMapper->SetInputData(ps.source->baseImage()); - ps.baseMapper->Update(); - } - ps.baseVolume->SetMapper(ps.baseMapper); - ps.baseVolume->SetProperty(ps.prop); - ps.baseVolume->SetUserTransform(ps.world); - - ps.hiresMapper = vtkSmartPointer::New(); - ps.hiresMapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode); + ps.mapper = vtkSmartPointer::New(); + ps.mapper->SetRequestedRenderMode(vtkSmartVolumeMapper::GPURenderMode); // #1 拖动降采样:交互式采样距离自适应(拖动→大步长降采样跟手,松手→全质量)。 - ps.hiresMapper->SetAutoAdjustSampleDistances(1); - ps.hiresMapper->SetInteractiveAdjustSampleDistances(1); - ps.hiresVolume = vtkSmartPointer::New(); - ps.hiresVolume->SetMapper(ps.hiresMapper); - ps.hiresVolume->SetProperty(ps.prop); - ps.hiresVolume->SetUserTransform(ps.world); - ps.hiresVolume->SetVisibility(0); // 无就绪高清前不显(底图兜底) + ps.mapper->SetAutoAdjustSampleDistances(1); + ps.mapper->SetInteractiveAdjustSampleDistances(1); + ps.volume = vtkSmartPointer::New(); + if (ps.source->baseImage() != nullptr) { + ps.mapper->SetInputData(ps.source->baseImage()); + ps.mapper->Update(); + ps.currentImg = ps.source->baseImage(); // 起步即有图(不空白) + } + ps.volume->SetMapper(ps.mapper); + ps.volume->SetProperty(ps.prop); + ps.volume->SetUserTransform(ps.world); // 该线世界 AABB(底图模型盒经 T 变换的 8 角包络)→ 视锥裁剪用。 if (ps.source->baseImage() != nullptr) { @@ -4439,11 +4426,11 @@ int cmdViewAll(int argc, char** argv) { vtkOutputWindow::SetInstance(capWin); for (PlacedSource& ps : lines) { - ren->AddVolume(ps.baseVolume); // 先加底图 → 底层常渲 - ren->AddVolume(ps.hiresVolume); // 后加高清 → 叠在底图上 + ren->AddVolume(ps.volume); // P12:每线唯一体(引擎 LOD 单层) } std::cout << "[view-all] 已加入场景线数=" << lines.size() - << "(底图常驻 + 高清叠加,各 ≤16384 单纹理,绝不撞 GL 纹理墙)\n"; + << "(每线唯一体=" << lines.size() + << " 体,引擎 LOD 单层,各 ≤16384 单纹理,绝不撞 GL 纹理墙)\n"; ViewAllState st; st.lines = &lines;