You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pixel index overshoots our allocated array canvas #252
// --- Inside gsplat_cpu.cpp right after minx/maxx/miny/maxy are calculated ---
// 1. Intercept NaN or Infinite coordinates caused by bad Gaussian splits
if (std::isnan(minx) || std::isnan(maxx) || std::isinf(minx) || std::isinf(maxx) ||
std::isnan(miny) || std::isnan(maxy) || std::isinf(miny) || std::isinf(maxy)) {
continue; // Safely skip this broken Gaussian point and proceed to the next one
}
// 2. Clamp values to your legal screen boundaries to prevent massive underflows
minx = std::max(0, std::min(minx, width - 1));
maxx = std::max(0, std::min(maxx, width - 1));
miny = std::max(0, std::min(miny, height - 1));
maxy = std::max(0, std::min(maxy, height - 1));
According to AI:
Between version v1.1.5 and your current version v1.2.2, OpenSplat went through significant structural updates. The exact regression you are seeing is directly tied to a major tile-rasterization rewrite introduced in this release window.
The most relevant commit to look at is "Fix tile-bin overflow, compressed image cache" (#250). Here is the breakdown of how that change introduced your specific crash when handling larger datasets on the CPU:
1. The Tile-Bin Optimization Vector Overflow (The Root Issue)
In versions prior to v1.1.5, OpenSplat’s CPU rasterizer mapped 3D Gaussians to screen space using a conservative fixed matrix layout. To optimize rendering performance for larger scenes, the project maintainer introduced a more aggressive dynamic tile-binning mechanism.
• The Intended Change: It calculates a tight bounding box (minx, maxx, miny, maxy) around each projected splat, grouping them into 16×16 spatial tile indices to optimize thread dispatching.
• The Unintended Bug: The math assumes a standard, stable field-of-view matrix. When a scene suddenly scales up (like your jump to 140,472 initial points and 201 images), the densification interval at step 500 pushes newly generated, unrefined points to the absolute periphery of the projection plane. The formulas do not feature proper saturation or edge checks, causing minx and maxx to experience integer underflow/overflow bounds checking failure (slipping into deep negative integer limits).
Multi-Threaded Cache Mismatches
Commit #250 also introduced a complex compressed image memory cache system designed to keep VRAM/RAM lean.
• The Bug: When rendering on the CPU, different thread processes dynamically scale and compress/decompress active texture blocks on-the-fly based on your image downsample scaling parameter (-d 2).
• The Collision: At step 500, a massive vector memory reallocation event fires off to accommodate the thousands of newly spawned points. The multi-threaded rasterizer threads continue calculating bounding footprints using the downscaled frame size tracker, but the underlying shared tile-state cache size matrices (pFinalTs) temporarily desynchronize during the rapid memory update. This results in the thread tracking an invalid index number (like 3961716), walking right over the allocated bounds of the array, and triggering the hard 0xC0000005 Access Violation.
Why Your In-Line Filters Fixed It
By inserting our std::isnan / std::isinf guards and clamping minx and maxx tightly against (width - 1), you directly intercepted the math that this v1.2.2 optimization pass missed. You forced the new tile-binning logic to safely drop the extreme projection vectors that were missing validation checks in the current master repository branch!
I'm going to let v1.1.5 run for a few thousand iterations and then compare the results. I haven't applied the In-Line filtering as AI is suggesting yet.
Activity
lruminski commentedon Oct 7, 2026
lruminski commentedon Oct 7, 2026
could it be that i was using an undistorted image set?
lruminski commentedon Oct 7, 2026
no, still happens with the original image set.
lruminski commentedon Oct 7, 2026
do you think I need to check if the index is negative as well @pierotofy?
lruminski commentedon Oct 8, 2026
it's also crashing on gsplat_cpu.cpp:266,
for some reason minx and maxx are both very large negative values.
I'm going back to v1.5.5 to see if I'm getting similar crashes.
lruminski commentedon Oct 8, 2026
According to AI:
Between version v1.1.5 and your current version v1.2.2, OpenSplat went through significant structural updates. The exact regression you are seeing is directly tied to a major tile-rasterization rewrite introduced in this release window.
The most relevant commit to look at is "Fix tile-bin overflow, compressed image cache" (#250). Here is the breakdown of how that change introduced your specific crash when handling larger datasets on the CPU:
1. The Tile-Bin Optimization Vector Overflow (The Root Issue)
In versions prior to v1.1.5, OpenSplat’s CPU rasterizer mapped 3D Gaussians to screen space using a conservative fixed matrix layout. To optimize rendering performance for larger scenes, the project maintainer introduced a more aggressive dynamic tile-binning mechanism.
• The Intended Change: It calculates a tight bounding box (minx, maxx, miny, maxy) around each projected splat, grouping them into 16×16 spatial tile indices to optimize thread dispatching.
• The Unintended Bug: The math assumes a standard, stable field-of-view matrix. When a scene suddenly scales up (like your jump to 140,472 initial points and 201 images), the densification interval at step 500 pushes newly generated, unrefined points to the absolute periphery of the projection plane. The formulas do not feature proper saturation or edge checks, causing minx and maxx to experience integer underflow/overflow bounds checking failure (slipping into deep negative integer limits).
Commit #250 also introduced a complex compressed image memory cache system designed to keep VRAM/RAM lean.
• The Bug: When rendering on the CPU, different thread processes dynamically scale and compress/decompress active texture blocks on-the-fly based on your image downsample scaling parameter (-d 2).
• The Collision: At step 500, a massive vector memory reallocation event fires off to accommodate the thousands of newly spawned points. The multi-threaded rasterizer threads continue calculating bounding footprints using the downscaled frame size tracker, but the underlying shared tile-state cache size matrices (pFinalTs) temporarily desynchronize during the rapid memory update. This results in the thread tracking an invalid index number (like 3961716), walking right over the allocated bounds of the array, and triggering the hard 0xC0000005 Access Violation.
Why Your In-Line Filters Fixed It
By inserting our std::isnan / std::isinf guards and clamping minx and maxx tightly against (width - 1), you directly intercepted the math that this v1.2.2 optimization pass missed. You forced the new tile-binning logic to safely drop the extreme projection vectors that were missing validation checks in the current master repository branch!
lruminski commentedon Oct 8, 2026
I'm going to let v1.1.5 run for a few thousand iterations and then compare the results. I haven't applied the In-Line filtering as AI is suggesting yet.