LioQing/wgpu-3dgs-viewer
LioQing/wgpu-3dgs-viewer has 65 GitHub stars and 12 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 09:32 UTC. Last push 2026-10-13.
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
A 3D Gaussian Splatting Viewer written in Rust using wgpu.
Creative & MediaREADME.md
Original3D Gaussian Splatting Viewer
...written in Rust using wgpu.

Overview
This library displays 3D Gaussian Splatting models with wgpu. It includes a ready‑to‑use pipeline and modular pieces you can swap out.
- Rendering pipeline
- Preprocess: cull off‑screen points and set up indirect draw data.
- Sort and draw: sort by depth and draw the Gaussians.
- Modes: Gaussians may be displayed as splat, ellipse, or point.
- Transforms: apply model or per-Gaussian transforms.
- Abstraction for renderer and buffers
- Viewer: one type that manages the buffers and pipelines.
- Low-level access: preprocessor, sorter, renderer, and their buffers can be used separately.
- Supports PLY and SPZ file formats.
- GPU buffer allows for compressed and uncompressed formats.
- Optional features
- Multi-model: render many models with custom draw orders.
- Selection: viewport selection (e.g. rectangle, brush) that marks Gaussians for editing.
- Lampshade sorting: an alternative depth sorter for eligible NVIDIA/Vulkan devices, requires the
lampshade-sortfeature.
- Shaders
- WGSL shaders packaged with WESL, you can extend or replace them.
Usage
You may read the documentation of the following types for more details:
- [
Viewer]: Manages buffers and renders a model.- [
Preprocessor]: Culls Gaussians and fills indirect args and depths. - [
DepthSorter]: Sorts Gaussians by depth on the GPU, defaults to [RadixSorter], can be customized. - [
Renderer]: Draws Gaussians with the selected display mode.
- [
- [
MultiModelViewer]: [Viewer] equivalent for multiple models. Requiresmulti-modelfeature. - [
selection]: Select Gaussians based on viewport interactions, e.g. rectangle or brush. Requiresselectionfeature.
[!TIP]
The design principles of this crate are to provide modularity and flexibility to the end user of the API, which means exposing low-level WebGPU APIs. However, this means that you have to take care of your code when accessing low-level components. You risk breaking things at run-time if you don't handle them properly.
If you do not want to take the risk, consider using the higher-level wrappers and avoid any instances of passing
wgputypes into functions.
Simple Viewer
You can use [Viewer] to render a single 3D Gaussian Splatting model:
The model's SH storage degree must match the viewer's [core::GaussianPod] layout.
[DefaultGaussianPod] uses core::PackedGaussian<core::ShSingle, core::CovSingle> with
degree 3. Choose a matching layout for other storage degrees. Viewer creation returns
[ViewerCreateError::ShDegreeMismatch] on a mismatch, without implicitly truncating or
zero-extending SH coefficients. [MultiModelViewer::insert_model] and
[MultiModelViewer::insert_model_with] also return Result and leave existing models
unchanged on a degree mismatch.
use wgpu_3dgs_viewer as gs;
use wgpu_3dgs_viewer::core::glam::UVec2;
// Setup wgpu...
// Read the Gaussians from the .ply file
let gaussians = gs::core::Gaussians::read_from_file(model_path, gs::core::GaussiansSource::Ply)
.expect("gaussians");
// Create the camera
let camera = gs::Camera::new(0.1..1e4, 60f32.to_radians());
// Create the viewer
let mut viewer = gs::Viewer::new(&device, config.view_formats[0], &gaussians).expect("viewer");
// Setup camera parameters...
// Update the viewer's camera buffer
viewer.update_camera(
&queue,
&camera,
UVec2::new(config.width, config.height),
);
// Create wgpu command encoder...
// Render the model
viewer.render(&mut encoder, &texture_view);
Optional Lampshade depth sorting
The lampshade-sort feature provides [LampshadeSorter], a [DepthSorter] backed by
Lampshade's native counted sorter for eligible
NVIDIA/Vulkan devices on native targets. [RadixSorter] remains the default, and
[LampshadeSorter] falls back to it on unsupported native devices.
Since the sorter is dependency injected, add the optional feature and inject it when creating the viewer:
use wgpu_3dgs_viewer::{
DefaultGaussianPod, LampshadeSorter, Viewer, ViewerCreateOptions,
core::{BufferWrapper, GaussiansBuffer},
};
let viewer = Viewer::<DefaultGaussianPod, LampshadeSorter>::new_with_options(
&device,
config.view_formats[0],
&gaussians,
ViewerCreateOptions {
depth_stencil: None,
gaussians_buffer_usage: GaussiansBuffer::<DefaultGaussianPod>::DEFAULT_USAGES,
color_write_mask: wgpu::ColorWrites::ALL,
cache: None,
depth_sorter_factory: |ctx| LampshadeSorter::new(ctx),
phantom_data: Default::default(),
},
)
.expect("viewer");
Apply lampshade::KeyValueSoaSorter::requirements(&adapter) when creating the device; enabling
the Cargo feature alone does not enable the required device features and limits.
LampshadeSorter::is_accelerated reports whether the accelerated path is active.
The fast path consumes the GPU-written draw instance_count without CPU readback and prepares its
workspace once. It also retains the embedded sorter's resources for compatibility, so it uses
additional memory.
[LampshadeSorter] also supports [MultiModelViewer]. Inject
LampshadeSorter::new_without_bind_groups instead, which prepares one Lampshade plan per model:
use wgpu_3dgs_viewer::{
DefaultGaussianPod, LampshadeSorter, MultiModelViewer, MultiModelViewerCreateOptions,
core::{BufferWrapper, GaussiansBuffer},
};
let viewer = MultiModelViewer::<DefaultGaussianPod, LampshadeSorter<()>>::new_with_options(
&device,
config.view_formats[0],
MultiModelViewerCreateOptions {
depth_stencil: None,
gaussians_buffer_usage: GaussiansBuffer::<DefaultGaussianPod>::DEFAULT_USAGES,
color_write_mask: wgpu::ColorWrites::ALL,
cache: None,
depth_sorter_factory: |ctx| LampshadeSorter::new_without_bind_groups(ctx.device),
phantom_data: Default::default(),
},
)
.expect("viewer");
Examples
See the examples directory for usage examples.
Dependencies
This crate depends on the following crates:
wgpu-3dgs-viewer |
wgpu |
glam |
wesl |
|---|---|---|---|
| 0.8 | 30.0 | 0.33 | 0.4 |
| 0.7 | 29.0 | 0.32 | 0.3 |
| 0.6 | 28.0 | 0.30 | 0.3 |
| 0.5 | 27.0 | 0.30 | 0.2 |
| 0.4 | 26.0 | 0.30 | 0.2 |
| 0.3 | 25.0 | 0.30 | N/A |
| 0.1 - 0.2 | 24.0 | 0.29 | N/A |
Related Crates
Acknowledgements
This crate uses modified code from KeKsBoTer's wgpu_sort.
References are also taken from other 3D Gaussian splatting renderer implemntations, including antimatter15's splat, KeKsBoTer's web-splat, and Aras' Unity Gaussian Splatting.