Skip to content

Add lidar point cloud support via OptiX sphere primitives#58

Merged
brendancol merged 1 commit intomasterfrom
feature/point-cloud-support
Feb 25, 2026
Merged

Add lidar point cloud support via OptiX sphere primitives#58
brendancol merged 1 commit intomasterfrom
feature/point-cloud-support

Conversation

@brendancol
Copy link
Contributor

Summary

  • Adds hardware-accelerated point cloud rendering using OptiX sphere primitives (BuildInputSphereArray)
  • New place_pointcloud() accessor method for loading and rendering LAS/LAZ/numpy point clouds on terrain
  • Extends pyoptix bindings with sphere primitive support (BuildInputSphereArray, built-in IS module)
  • New closest-hit shader (__closesthit__sphere) with proper world-space normal computation
  • Point cloud loading utilities with ASPRS classification filtering, return number filtering, spatial bounds cropping, and subsampling
  • Per-point RGBA coloring via GPU buffer with elevation, intensity, classification, RGB, and solid color modes

Changes

  • cuda/common.h: Added point_colors field to Params struct (88 → 96 bytes)
  • cuda/kernel.cu: Added __closesthit__sphere() program using optixGetSphereData() and optixGetObjectToWorldTransformMatrix()
  • rtxpy/rtx.py: Sphere built-in IS module, hit group (SBT offset 3), _build_gas_for_spheres(), add_sphere_geometry(), updated IAS/SBT/params for 4th geometry type
  • rtxpy/accessor.py: place_pointcloud() method with geo→pixel coordinate transform, terrain Z-snapping, and color generation
  • rtxpy/pointcloud.py: New module with load_pointcloud() (LAS/LAZ/numpy/callable), build_colors(), ASPRS classification color map
  • rtxpy/kernel.ptx: Recompiled with sphere closest-hit program

Test plan

  • Single sphere hit and normal verification
  • Per-point radii support
  • Primitive index identification
  • Miss detection
  • 1M sphere scale test (GAS build ~22ms)
  • place_pointcloud() accessor pipeline (1000 points)
  • All color modes (elevation, intensity, classification, rgb, solid)

Closes #55

Introduces hardware-accelerated sphere intersection for rendering point
clouds as splats. Each point becomes an OptiX sphere with per-point
radius and RGBA color.

Engine (rtx.py):
- _build_gas_for_spheres() using BuildInputSphereArray
- RTX.add_sphere_geometry() with uniform or per-point radii
- Built-in sphere IS module + dedicated closest-hit program
- SBT offset 3 for sphere hit group routing
- Per-point color buffer in Params struct (96 bytes)

Kernel (kernel.cu):
- __closesthit__sphere: normal via optixGetSphereData() +
  object-to-world transform for correct world-space normals

Data loading (pointcloud.py):
- load_pointcloud() for LAS/LAZ (via laspy), numpy arrays, callables
- Filtering by classification, return number, bounds, subsample
- build_colors() with elevation/intensity/classification/rgb/solid modes
- ASPRS standard classification color table

Accessor (accessor.py):
- place_pointcloud() method with coordinate transform, Z snapping,
  and automatic color generation

Tested: 1M spheres built in 22ms, correct normals and hit detection.
@brendancol
Copy link
Contributor Author

fixes #55

@brendancol
Copy link
Contributor Author

requires pyoptix-contrib>=0.1.2

@brendancol brendancol merged commit 3018f5e into master Feb 25, 2026
1 check passed
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.

Add lidar point cloud support via OptiX sphere primitives

1 participant