A Rust-native 3D visualization library for geometric data, inspired by Polyscope.
![]() Materials |
![]() Volume Mesh |
![]() Camera View |
![]() Volume Grid |
polyscope-rs is a viewer and user interface for 3D data such as meshes and point clouds. It allows you to register your data and quickly generate informative visualizations, either programmatically or via a dynamic GUI.
This is a Rust reimplementation of the original C++ Polyscope library, using modern Rust graphics libraries (wgpu, winit, egui).
This project is an experiment in AI-driven software development. I have limited Rust experience but have used Polyscope extensively and contributed PRs to the original C++ library. It validates the hypothesis that languages with informative compiler feedback (like Rust) work better with AI-assisted development.
Note: This project has reached full feature parity with C++ Polyscope 2.x but is still maturing. Contributions and feedback are welcome in the Discussions section.
Current Version: 0.5.6
Feature Parity: Full parity with C++ Polyscope 2.x for all core functionality
| Feature | Status |
|---|---|
| Point Clouds | ✅ Full support |
| Surface Meshes | ✅ Triangles + arbitrary polygons, full quantity support |
| Curve Networks | ✅ Full support |
| Volume Meshes | ✅ Tet/Hex cells |
| Volume Grids | ✅ Node/cell scalars, gridcube + isosurface (marching cubes) |
| Camera Views | ✅ Full support |
| Materials | ✅ 8 built-in + custom material loading |
| Color Maps | ✅ 10+ maps |
| Ground Plane | ✅ Tile/Shadow/Reflection |
| Slice Planes | ✅ Up to 4 planes |
| Groups | ✅ Hierarchical |
| Gizmos | ✅ Translate/Rotate/Scale |
| Transparency | ✅ Depth peeling (Pretty) + alpha blending (Simple) |
| Tone Mapping | ✅ HDR pipeline |
| SSAO | ✅ Ambient occlusion |
| RGBA Colors | ✅ Per-element alpha on all structures |
| Headless Rendering | ✅ render_to_image() / render_to_file() without a window |
| Screenshots | ✅ PNG/JPEG export |
| Picking | ✅ Structure/Element |
| Camera Navigation | ✅ Turntable/Free/Planar/Arcball/First-person |
| Parameterization | ✅ Checker/Grid/Local styles |
| Intrinsic Vectors | ✅ Tangent-space with symmetry |
| One-Forms | ✅ Edge-based differential forms |
| Floating Quantities | ✅ Scalar/Color/Render images |
See docs/architecture-differences.md for a detailed comparison with C++ Polyscope.
- Point Clouds - Visualize point sets with scalar, vector, and color quantities
- Surface Meshes - Render triangular meshes with scalars, vectors, colors, parameterization, intrinsic vectors, and one-forms
- Curve Networks - Display networks of curves and edges
- Volume Meshes - Visualize tetrahedral and hexahedral meshes
- Volume Grids - Render regular 3D grids with node/cell scalar quantities
- Camera Views - Visualize camera frustums and poses
- Slice Planes - Cut through geometry to see interiors
- Groups - Organize structures hierarchically
- Gizmos - Interactive transform manipulation
use polyscope_rs::*;
fn main() -> Result<()> {
// Initialize polyscope
init()?;
// Register a point cloud
let points = vec![
Vec3::new(0.0, 0.0, 0.0),
Vec3::new(1.0, 0.0, 0.0),
Vec3::new(0.0, 1.0, 0.0),
];
let pc = register_point_cloud("my points", points);
// Add a scalar quantity
pc.add_scalar_quantity("height", vec![0.0, 0.5, 1.0]);
// Show the viewer
show();
Ok(())
}Render scenes without opening a window -- useful for batch processing, automated testing, and server-side rendering:
use polyscope_rs::*;
fn main() -> Result<()> {
init()?;
register_point_cloud("pts", vec![Vec3::ZERO, Vec3::X, Vec3::Y]);
// Render to pixel buffer (RGBA, 4 bytes per pixel)
let pixels = render_to_image(800, 600)?;
// Or render directly to a PNG file
render_to_file("output.png", 800, 600)?;
Ok(())
}Add to your Cargo.toml:
[dependencies]
polyscope-rs = "0.5"Run any demo with:
cargo run --example <demo_name>| Demo | Command | Description |
|---|---|---|
| Point Cloud | cargo run --example point_cloud_demo |
Scalar, vector, and color quantities on point sets |
| Surface Mesh | cargo run --example surface_mesh_demo |
Stanford Bunny with full quantity support |
| Curve Network | cargo run --example curve_network_demo |
Curve and edge network visualization |
| Volume Mesh | cargo run --example volume_mesh_demo |
Tet/hex meshes with interior face detection and quantities |
| Volume Grid | cargo run --example volume_grid_demo |
Gridcube mode, isosurface (marching cubes), cell scalars |
| Camera View | cargo run --example camera_view_demo |
Camera frustum visualization |
| Slice Planes | cargo run --example slice_plane_demo |
Fragment-level slicing, volume mesh capping, gizmo control |
| Groups & Gizmos | cargo run --example groups_and_gizmos_demo |
Hierarchical groups, transform gizmos, structure selection |
| Ground Plane | cargo run --example ground_plane_demo |
Ground plane modes, shadows, reflections |
| Polygon Mesh | cargo run --example polygon_mesh_demo |
Arbitrary n-gon faces (quads, hexagons, octagons) |
| Materials | cargo run --example materials_demo |
All 8 matcap materials across structure types |
| Transparency | cargo run --example transparency_demo |
Depth peeling (Pretty) and alpha blending (Simple) modes |
Controls (common to all demos):
- Left drag: Orbit camera
- Right drag: Pan camera
- Scroll: Zoom
- ESC: Exit
polyscope-rs uses a paradigm of structures and quantities:
- A structure is a geometric object in the scene (point cloud, mesh, etc.)
- A quantity is data associated with a structure (scalar field, vector field, colors)
For detailed documentation, see the docs/ directory.
polyscope- Main crate with public APIpolyscope-core- Core traits and state managementpolyscope-render- wgpu rendering backendpolyscope-ui- egui UI integrationpolyscope-structures- Structure implementations
| Component | Library | C++ Polyscope Equivalent |
|---|---|---|
| Rendering | wgpu | OpenGL |
| UI | egui | Dear ImGui (C++) |
| Math | glam | GLM |
| Windowing | winit | GLFW |
| Shaders | WGSL | GLSL |
| Build | Cargo | CMake |
For developers familiar with the C++ version or considering migration, see:
- Architecture Differences - C++ vs Rust rendering implementation differences
- Feature Status & Roadmap - Feature comparison tables and planned work
- Development Guide - Adding structures/quantities, API patterns, migration tips
- Graphics Backend: Uses wgpu instead of OpenGL, providing native support for Vulkan, Metal, DirectX 12, and WebGPU
- Error Handling: Uses Rust's
Result<T, E>instead of exceptions - Memory Safety: Leverages Rust's ownership model for memory safety
- API Style: Uses handles and closure-based access instead of raw pointers
| Platform | Status |
|---|---|
| Linux (X11/Wayland) | ✅ Tested |
| Windows | ✅ Tested |
| macOS | ✅ Should work |
| WebGPU | 🔄 Planned |
- Intermittent SIGSEGV on WSL2: When running under Windows Subsystem for Linux 2 with GPU passthrough, the application may occasionally crash with exit code 139 (SIGSEGV) inside the GPU driver. This is a known class of WSL2/GPU driver instability issues, not a bug in polyscope-rs. Native Linux, Windows, and macOS are unaffected.
- wgpu late binding validation workaround: All uniform buffer bindings use explicit
min_binding_sizeto work around wgpu#7359, where late buffer binding size validation cross-contaminates between pipelines in the same command encoder. This is transparent to users but relevant for contributors adding new pipelines or bind group layouts. - Pretty mode non-linear opacity: In Pretty (depth peeling) transparency mode, opacity response is non-linear compared to Simple mode. Both front and back faces of closed meshes are peeled, giving effective alpha =
2α - α². This is inherent to depth peeling and matches C++ Polyscope behavior. Transparency only becomes visually apparent at lower opacity values. - Pretty mode f16 depth precision: The depth peeling min-depth texture uses
Rgba16Float(half precision) because WebGPU'sR32Floatdoes not support blending without the optionalfloat32-blendablefeature. This requires a larger depth comparison epsilon (2e-3) than C++ Polyscope's1e-6(which uses 24-bit depth). Very closely spaced geometry layers (within 0.002 NDC depth) may not be correctly distinguished during peeling.
MIT License - see LICENSE for details.
This project is inspired by the original Polyscope C++ library by Nicholas Sharp.
Contributions are welcome! Key areas where help is needed:
- Documentation and examples
- Testing on different platforms (macOS, WebGPU)




