mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
wgpu cull: contribution-cull defaults 2/10 → 3/15, env-var overrides
wgpu computes projected_px from view-Z distance (forward·(centre-eye)), which is the perspective-divide-correct denominator: an instance's on-screen radius really is world_radius * focal / z_view. GL computes the same value but with euclidean distance (sqrt(dx²+dy²+dz²)) — for off-axis instances euclidean > z_view, so GL underestimates screen size and culls more aggressively at the same numeric threshold. Concretely on the federation scene at the test camera, wgpu was drawing ~3× the instances GL drew despite identical 2/10 thresholds: wgpu obj 11067, hiz_rej 16532 vs GL obj 2310, hiz_rej 6823. Same fps (vsync-pinned), but ~30% more cull work for raster output that the user already wasn't seeing because GL had been quietly dropping it. Keeping wgpu's view-Z formula (more physically correct) and bumping the thresholds to 3.0 / 15.0 to match GL's effective drop rate. On the federation scene this lands obj/tri counts within ~10% of GL across the orbit, and shaves cull from 3.44 ms to 2.61 ms avg. basic.ifc parity is unchanged (its 3 instances clear 3 px easily). WGPU_MIN_PX / WGPU_MIN_PX_MOTION env vars added so the thresholds can be swept without rebuilding — needed while we visually confirm the new defaults across more scenes / cameras. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <future>
|
||||
#include <limits>
|
||||
@@ -1302,6 +1303,25 @@ bool WgpuViewportWindow::initWgpu() {
|
||||
wgpuSetLogCallback(onWgpuLog, nullptr);
|
||||
wgpuSetLogLevel(WGPULogLevel_Warn);
|
||||
|
||||
// Env-var overrides for contribution-cull thresholds. wgpu uses
|
||||
// view-Z (perspective-divide-correct) for projected_px, whereas the
|
||||
// GL backend uses euclidean distance — so for off-axis instances
|
||||
// wgpu computes a larger projected_px and is less aggressive at the
|
||||
// same numeric threshold. These knobs exist to let us sweep matching
|
||||
// values during the perf-parity push without rebuilding.
|
||||
if (const char* s = std::getenv("WGPU_MIN_PX")) {
|
||||
const float v = float(std::atof(s));
|
||||
if (v >= 0.0f) min_pixel_radius_ = v;
|
||||
qInfo().noquote().nospace()
|
||||
<< "[wgpu cull] WGPU_MIN_PX=" << min_pixel_radius_;
|
||||
}
|
||||
if (const char* s = std::getenv("WGPU_MIN_PX_MOTION")) {
|
||||
const float v = float(std::atof(s));
|
||||
if (v >= 0.0f) motion_min_pixel_radius_ = v;
|
||||
qInfo().noquote().nospace()
|
||||
<< "[wgpu cull] WGPU_MIN_PX_MOTION=" << motion_min_pixel_radius_;
|
||||
}
|
||||
|
||||
instance_ = wgpuCreateInstance(nullptr);
|
||||
if (!instance_) {
|
||||
qWarning() << "wgpuCreateInstance returned null";
|
||||
|
||||
@@ -387,9 +387,18 @@ private:
|
||||
// Contribution-cull thresholds. Still-frame uses min_pixel_radius_;
|
||||
// when the camera changed since last frame, the bigger motion threshold
|
||||
// kicks in to drop more sub-pixel detail (and slash per-frame cull cost).
|
||||
// Matches AppSettings::minPixelRadius / motionMinPixelRadius in GL.
|
||||
float min_pixel_radius_ = 2.0f;
|
||||
float motion_min_pixel_radius_ = 10.0f;
|
||||
//
|
||||
// GL ships 2.0 / 10.0, but uses euclidean distance for projected_px
|
||||
// (sqrt(dx² + dy² + dz²)) while wgpu uses view-Z distance (the
|
||||
// perspective-divide-correct denominator). For off-axis instances
|
||||
// view_z < euclidean, so wgpu's projected_px is larger than GL's at
|
||||
// the same numeric threshold — i.e. wgpu is structurally less
|
||||
// aggressive. Bumping to 3.0 / 15.0 compensates so the effective drop
|
||||
// rate matches GL's; on the federation scene this lands obj/tri
|
||||
// counts within ~10% of GL's across an orbit (vs ~3× without the
|
||||
// bump). Override at runtime via WGPU_MIN_PX / WGPU_MIN_PX_MOTION.
|
||||
float min_pixel_radius_ = 3.0f;
|
||||
float motion_min_pixel_radius_ = 15.0f;
|
||||
|
||||
public:
|
||||
// Master switch for HiZ occlusion. Set false to skip the depth resolve
|
||||
|
||||
Reference in New Issue
Block a user