Skip to content

First-class spherical undistort support#1369

Draft
lyehe wants to merge 7 commits into
MrNeRF:masterfrom
lyehe:feature/spherical-cube-undistort
Draft

First-class spherical undistort support#1369
lyehe wants to merge 7 commits into
MrNeRF:masterfrom
lyehe:feature/spherical-cube-undistort

Conversation

@lyehe

@lyehe lyehe commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR makes the existing --undistort path work for spherical/equirectangular COLMAP datasets by expanding each panorama into internal pinhole tangent views during loading.

The current sampling uses 12 icosahedral directions at 90 degrees FOV. The generated views stay virtual: they reuse the source panorama and mask paths, flow through the existing projection-aware image loader/cache, and do not write precomputed split images to disk. That keeps the CLI and UI unchanged while giving the trainer pinhole-compatible views for spherical data.

Behavior

  • --undistort on spherical COLMAP imports expands each equirectangular panorama into 12 internal pinhole cameras.
  • Image loading, eval loading, masks, alpha masks, and immediate strategy image loads all use the same projection-aware loader path.
  • Without --undistort or --gut, spherical/non-pinhole datasets fail early with a direct message telling the user to choose one of those paths.
  • --gut remains the native non-pinhole training path.

Validation

  • Built LichtFeld-Studio in Release with ninja -C build LichtFeld-Studio.
  • Ran git diff --check.
  • Verified the no-undistort spherical path fails early with the expected prompt.
  • Ran a full campus parterre MRNF training pass with --undistort --strategy mrnf --iter 60000:
    • 37 panoramas expanded into 444 internal views.
    • 12 views/panorama, 90 degrees FOV, 1410 px auto face size.
    • Completed successfully in 461.847s at 129.9 iter/s.
    • Final output: 696,837 splats, final PLY and checkpoint written, empty stderr.
    • PLY sanity check: median opacity ~0.45; only ~0.43% of splats had opacity > 0.1 and max scale > 2.
  • ctest --test-dir build --output-on-failure reports no tests configured in this local build.

Copilot AI review requested due to automatic review settings July 4, 2026 08:53
@lyehe lyehe changed the title [codex] Add internal cube-face undistort for spherical COLMAP Train spherical COLMAP data with internal cube-face undistortion Jul 4, 2026
@lyehe lyehe changed the title Train spherical COLMAP data with internal cube-face undistortion First-class spherical undistort support Jul 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an internal “virtual cube-face” undistort path for spherical/equirectangular COLMAP cameras when training with --undistort, by expanding panoramas into six pinhole cube-face cameras and routing image/mask loading through projection-aware requests (without changing the UI/CLI or writing a cube_faces/ folder).

Changes:

  • Expand equirectangular cameras into internal cube-face pinhole cameras during training setup and preserve train/eval splits through the expansion.
  • Add CubeFaceProjection metadata to core::Camera and thread it through the pipelined image loader cache keys + decode paths (including alpha-as-mask and grayscale aux images).
  • Update trainer/strategies/metrics eval to request projection-aware images/masks via the pipelined loader, and tighten early validation/error messaging for unsupported camera models.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/training/training_setup.cpp Adds equirectangular→cube-face camera expansion for --undistort and applies split selection before expansion.
src/training/trainer.cpp Passes cube-face projection into immediate GT/mask loads; adjusts bilateral-grid sizing by UID range; adds early camera-model validation.
src/training/strategies/mrnf.cpp Routes immediate strategy image loads through projection-aware loader calls.
src/training/strategies/improved_gs_plus.cpp Routes immediate strategy image loads through projection-aware loader calls.
src/training/metrics/metrics.hpp Removes declarations for now-deleted non-pipelined eval helpers.
src/training/metrics/metrics.cpp Switches eval to a projection-aware pipelined dataloader for GT + masks/alpha-masks.
src/training/dataset.hpp Updates pipelined dataloader draining logic and propagates cube-face projection into image requests.
src/io/pipelined_image_loader.cpp Implements CPU-side cube-face reprojection on cache miss and threads projection into caching + decode for images/masks/alpha masks/aux grayscale.
src/io/include/io/pipelined_image_loader.hpp Extends request/worker structs and APIs to carry cube-face projection metadata.
src/core/include/core/cube_face_projection.hpp Introduces CubeFaceProjection data structure.
src/core/include/core/camera.hpp Adds cube-face projection storage/accessors on core::Camera.
src/core/camera.cpp Carries cube-face projection through moves/copies and adjusts image sizing/byte estimates for projected cameras.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +199 to +200
int next_uid = 0;

Comment thread src/training/trainer.cpp Outdated
Comment on lines +483 to +487
try {
inputs.gt_image = loader->load_image_immediate(
camera.image_path(),
make_metrics_load_params(gt_config, camera, true, true));
make_metrics_load_params(gt_config, camera, true, true),
camera.cube_face_projection());
@lyehe lyehe force-pushed the feature/spherical-cube-undistort branch from de5aac2 to d8f7b40 Compare July 4, 2026 09:24
@lyehe lyehe force-pushed the feature/spherical-cube-undistort branch from d8f7b40 to 165e33e Compare July 4, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants