ArthurBrussee/brush
55.3
Adequate · 30 September 2026
25.6k
lines of production code
Rust
primary language
2
measurements over time
What this system is
This system is a Rust-based implementation of 3D Gaussian Splatting that provides tools for training, rendering, and visualizing 3D scenes from image datasets. It supports multiple platforms including native desktop, Android, and Web (WASM), offering both an interactive GUI and a headless CLI for automated workflows. The core functionality includes GPU-accelerated differentiable rendering, configurable training pipelines with various loss metrics, and integration with external visualization tools like Rerun.io.
How it got here
2024 — Core infrastructure and training pipeline development
11 changes.
This period focused on establishing the foundational Rust workspace and building the core 3D Gaussian Splatting engine, including GPU-accelerated sorting, differentiable rendering, and modular training logic. Significant effort was directed toward creating robust data handling capabilities, such as cross-platform file selection, configurable dataset loading, and support for COLMAP and RealityCapture formats. The work also integrated real-time training visualization via Rerun and implemented comprehensive testing to ensure stability across native and WebGPU targets.
2025 — Testing infrastructure and data format support
7 changes.
This period focused on establishing robust validation and benchmarking frameworks for the rendering and training pipelines, including reference test harnesses and gradient verification. It also expanded data handling capabilities by introducing a cross-platform virtual file system, PLY import/export for Gaussian Splat models, and procedural macros for spherical harmonic data.
2026 — multi-platform expansion and GPU infrastructure
8 changes.
The project expanded its deployment capabilities by adding Android and Web (WASM) support to the main application and introducing a dedicated headless CLI for training. Concurrently, the underlying GPU infrastructure was strengthened through the migration of scan operations to CubeCL, the implementation of a thread-pinned async executor to prevent rendering corruption, and the addition of GPU-accelerated loss computation kernels.
Features
Add LPIPS perceptual loss model and conversion tool
Introduces a new LPIPS (Learned Perceptual Image Patch Similarity) model implementation in the \lpips\ crate, enabling perceptual difference calculations between image pairs using a VGG-based architecture. The change includes the core \LpipsModel\ with VGG blocks and heads, along with a \lpips-convert\ utility to transform PyTorch weights into the Burn format. This allows users to leverage this specific perceptual metric in their workflows.
crates/lpips · high confidence
Add Python reference generation tool for benchmark tests
A new Python project has been added to the \crates/brush-bench-test/test\_cases\ directory to generate reference gradients for the Rust test suite. This tool uses \gsplat\ to produce forward-render reference safetensors, providing a baseline for validation while noting that its backward pass is not used as a reference due to missing viewdir-to-mean paths. Users can install dependencies via \uv\ and run \generate\_reference.py\ to create new samples or \bench.py\ to execute benchmarks.
_crates/brush-bench-test/test\cases · high confidence
Add Rerun integration for training visualization and logging
The \brush-rerun\ crate now provides a configurable integration with Rerun.io, allowing users to enable real-time visualization of training progress and results. Users can enable logging via the \--rerun-enabled\ flag and control the frequency of logged splat point clouds, training statistics, and distribution metrics. The integration logs 3D splat ellipsoids (including position, rotation, scale, and color) to the Rerun viewer, displays training loss and performance metrics (PSNR, SSIM) as time-series data, and logs ground-truth images once as static assets. A declarative blueprint is automatically sent to the Rerun viewer to organize these logs into a structured UI with labeled axes and views.
crates/brush-rerun · high confidence
Add procedural macros for spherical harmonic field generation
The \brush-serde-macros\ crate has been added, introducing three procedural macros to streamline the handling of spherical harmonic (SH) data. The \generate\_sh\_fields\ attribute macro automatically expands a marker field into 72 individual \f\_rest\_N\ coefficients, while the \sh\_field\_names\ macro provides a compile-time array of these field names. Additionally, the \impl\_coeffs\ macro generates a helper method to retrieve all SH coefficients as a fixed-size array, reducing boilerplate and allocation overhead in structs that utilize SH representations.
crates/brush-serde-macros · high confidence
Add support for RealityCapture/Postshot CSV datasets
Users can now load 3D scenes from RealityCapture and Postshot exports by providing a CSV file containing camera parameters (pose, focal length, distortion) alongside images. The importer parses the CSV header to locate required columns, handles radial/tangential distortion coefficients (approximating 4th-order radial terms with 3rd-order), and automatically matches images and masks using the filenames listed in the CSV.
crates/brush-dataset/src/formats · high confidence
Brush app now supports Android and Web (WASM) platforms
The Brush application is now available on Android and Web browsers in addition to desktop. This change introduces the necessary platform-specific entry points (Android \MainActivity\ and Rust \android.rs\, WASM stubs), a Java file picker for loading datasets on Android, and PWA assets (manifest and service worker) for web deployment. The core UI remains built with egui/eframe, but the app now compiles as a native binary for desktop, a shared library for Android, and a WASM module for the web.
apps/brush-app · high confidence
Introduce BrushVfs with cross-platform data source support
The \brush-vfs\ crate now provides a unified virtual file system that supports loading data from local files, directories, and URLs. On native platforms, it uses standard file system paths and the \reqwest\ library for HTTP/HTTPS fetching. On WebAssembly (WASM), it switches to the browser's \web\_sys\ fetch API for URL loading and utilizes the File System Access API (\rrfd::wasm::DirectoryHandle\) for directory selection, ensuring compatibility with browser security models. The VFS also normalizes paths for case-insensitive lookups, improving reliability on case-sensitive file systems.
crates/brush-vfs · high confidence
Introduce PLY import and export for Gaussian Splats
The \brush-serde\ crate now provides functionality to load and save Gaussian Splat models as PLY files. Users can export splats with dynamic spherical harmonic (SH) coefficient handling to avoid unnecessary data bloat, and import PLY files with support for subsampling large initial point clouds to fit memory budgets. The import process also supports quantized formats and streaming reads for better performance on large files.
crates/brush-serde · high confidence
Introduce rrfd crate for cross-platform file and directory selection
The new \rrfd\ crate provides a unified API for file and directory operations across native, Web (WASM), and Android platforms. On native systems, it leverages \rfd\ for standard file and folder picking. On the web, it implements directory support via the File System Access API, allowing users to select directories and read files recursively through a \DirectoryHandle\. On Android, it introduces a JNI-based file picker that communicates with the Java side via file descriptors, enabling file selection where native dialogs are unavailable. Note that directory picking and file saving are currently unsupported on Android.
crates/rrfd/src · high confidence
Introduce standalone brush-cli binary for headless training
A new \brush-cli\ crate has been added, providing a lightweight, headless binary dedicated to training. Unlike the main \brush\ application which includes a viewer, this CLI tool is designed for quick iteration and automated workflows; it enforces that a data source is provided when the viewer is disabled and runs the training process on a dedicated thread while displaying progress via a terminal UI.
apps/brush-cli · high confidence
Introduce structured training process and configuration system
The \brush-process\ crate now provides a unified, stream-based architecture for training and loading Gaussian splats. It introduces a \TrainStreamConfig\ that consolidates training, model, dataset, and process settings, supporting persistence via \args.txt\ files in the virtual file system. The system manages the training lifecycle through a \RunningProcess\ that emits structured \ProcessMessage\ events (such as \StartLoading\, \SplatsUpdated\, and \TrainStep\) to consumers, while using a \Slot\ mechanism to publish evolving splat views. This replaces ad-hoc argument handling with a robust, serializable configuration model that supports merging CLI arguments with file-based defaults.
crates/brush-process · high confidence
New C FFI for training models
Added a native-only C-compatible interface (brush-c) that exposes a \train\_and\_save\ function, allowing external applications to initiate model training from a dataset path with configurable options and receive progress updates via a callback. The implementation includes safety measures to catch Rust panics across the FFI boundary and prevent process crashes, along with integration tests verifying successful training, error handling for invalid paths, and null-pointer safety.
apps/brush-c · high confidence
New COLMAP data reader library
Added a new Rust library (crates/colmap-reader) that parses COLMAP text-based model files into structured data types. It supports multiple camera models (e.g., Pinhole, OpenCV, Fisheye) and extracts camera parameters, image poses, and 3D point data. The parser includes robustness improvements, such as tolerating MSVC-style NaN spellings in float values, to handle buggy or non-standard COLMAP exports.
crates/colmap-reader · high confidence
New GPU-accelerated image loss computation with PSNR helpers
The \brush-loss\ crate now provides GPU-based image loss kernels for Brush, computing a weighted combination of L1 and SSIM metrics with optional background compositing and alpha masking folded directly into the kernel to avoid materializing intermediate float tensors. It includes a forward-only evaluation function for per-pixel loss maps and adds PSNR calculation helpers that floor MSE to prevent infinite values for identical images.
crates/brush-loss/src · high confidence
New GPU-accelerated radix sort implementation
The \brush-sort\ crate now provides a \radix\_argsort\ function that performs sorting on the GPU using the CubeCL backend. This implementation replaces previous approaches with a multi-pass radix sort (4 bits per pass) utilizing custom WGSL kernels for counting, reduction, scanning, and scattering, enabling efficient sorting of large datasets directly on the device.
crates/brush-sort/src · high confidence
New brush-render crate with differentiable Gaussian splatting and backward kernels
The \brush-render\ crate has been introduced to house the core Gaussian splatting rendering logic, including a new differentiable backward pass for training. This change adds GPU-accelerated backward kernels (ported to CubeCL) for rasterization and projection, enabling gradient computation for splat parameters. It also introduces support for advanced camera models (Kannala-Brandt4, RadialTangential8, ThinPrismFisheye) with proper distortion handling and fold-aware culling, and provides a \BoundingBox\ utility with NaN-safe median size calculation. The rendering pipeline now supports Mip-Splatting 3D filtering and smooth alpha cutoffs for more stable training gradients.
crates/brush-render/src · high confidence
New modular training crate with configurable optimization and refinement
The \brush-train\ crate has been introduced to centralize 3D Gaussian Splatting training logic, exposing a comprehensive \TrainConfig\ for controlling learning rates (per-parameter), refinement thresholds, SSIM/LPIPS loss weights, and LOD generation. It implements a custom \AdamScaled\ optimizer that supports per-component learning-rate scaling and second-moment reduction, alongside new evaluation metrics (\eval.rs\), sensitivity-based pruning via PUP scores (\lod.rs\), and robust splat initialization (\splat\_init.rs\).
crates/brush-train · high confidence
Behavioural changes
Configurable dataset loading with scene batch caching and unit scaling
The dataset loading system now supports configurable image resolution limits, frame and point subsampling, and an evaluation split selection. Users can control how alpha channels and mask images are interpreted via an alpha mode setting, and can invert mask logic. A new scene batch cache allows tuning memory usage versus performance by setting a maximum cache size, which defaults to 6 GiB on native and 2 GiB on WebAssembly. Additionally, a units-per-meter option allows datasets reconstructed in non-metre units (e.g., millimetres) to be correctly scaled for training.
crates/brush-dataset/src · high confidence
GPU scan operations migrated to CubeCL
The device-wide inclusive prefix sum and associated block-scan kernels have been ported from the previous implementation to CubeCL. This change introduces new host-side tensor creation helpers and GPU kernels in \brush-cube\ and \brush-scan\ that leverage CubeCL's execution model, enabling the scan functionality to run on the WGPU backend via the Burn framework.
crates/brush-cube · high confidence
Introduces thread-pinned async executor to prevent GPU rendering corruption
The \brush-async\ crate now provides an \Actor\ abstraction that pins asynchronous tasks to a single OS thread (native) or the main JS event loop (Wasm). This change addresses visible rendering corruption—such as duplicate IDs, NaNs, and stale buffers—caused by the underlying GPU library's reliance on thread-local state being disrupted by Tokio's work-stealing scheduler. By ensuring futures remain on a single context, the system guarantees stable GPU stream IDs. Additionally, a new \AsyncMap\ utility is introduced to manage latest-value request/response workers, allowing UI components to queue updates that supersede older pending requests.
crates/brush-async · high confidence
Test coverage
Add benchmark and reference test harness for rendering and training; Added comprehensive rendering tests for splat visibility and large-scale performance; Added comprehensive test suite for splat rendering and training; Added isolated GPU sort microbenchmarks; Added smoke and invariant tests for loss kernels.
Dependencies
Initial workspace setup with Rust and JavaScript dependency manifests
The project is initialized as a Rust workspace (Cargo.toml) and a JavaScript workspace (package.json), establishing the foundational dependency graph for the application. The Rust side defines 33 member crates—including brush-app, brush-cli, brush-js, and core libraries like brush-render and brush-train—along with a Cargo.lock file that pins specific versions for key libraries such as wgpu 30, egui 0.36, rerun 0.36, and the Burn deep-learning framework (from the tracel-ai/burn main branch). The JavaScript side configures two web demo workspaces (brush-app/web and brush-js/web) using Vite, React, and Three.js, with a package-lock.json file recording the resolved npm dependencies.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 54 → 55 (+1.1)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 71 → 71 (+0.3)
- Architecture 96 → 97 (+1.2)
- Maturity 60 → 60 (+0.2)
- Readiness 81 → 77 (-4.4)
- Security 62 → 73 (+11.1)
- Accessibility 40 → 40 (+0.0)
- Performance 91 (new)
Resolved (23)
- Change coupling: eval.rs ↔ train.rs (crates/brush-train/src/eval.rs)
- Change coupling: lib.rs ↔ lib.rs (crates/brush-prefix-sum/src/lib.rs)
- Change coupling: render_aux.rs ↔ train.rs (crates/brush-render/src/render_aux.rs)
- Documentation: no installation or build instructions (crates/rrfd/README.md)
- Duplicated block (10 lines × 2) (crates/brush-sort/src/kernels.rs)
- Duplicated block (12 lines × 2) (crates/brush-loss/src/lib.rs)
- Duplicated block (12 lines × 3) (crates/brush-sort/src/kernels.rs)
- Duplicated block (29 lines × 2) (crates/brush-sort/src/kernels.rs)
- Duplicated block (7 lines × 2) (crates/brush-loss/src/lib.rs)
- Duplicated block (8 lines × 2) (crates/brush-loss/src/lib.rs)
- Duplicated block (9–10 lines × 2) (crates/brush-sort/src/kernels.rs)
- FunctionTooLong: brush_sort::kernels::sort_scatter_kernel (crates/brush-sort/src/kernels.rs)
- Hotspot: apps/brush-app/src/ui/app.rs (apps/brush-app/src/ui/app.rs)
- Hotspot: apps/brush-app/src/ui/scene.rs (apps/brush-app/src/ui/scene.rs)
- Hotspot: crates/brush-loss/src/lib.rs (crates/brush-loss/src/lib.rs)
- Hotspot: crates/brush-render/src/kernels/rasterize.rs (crates/brush-render/src/kernels/rasterize.rs)
- Hotspot: crates/brush-train/src/train.rs (crates/brush-train/src/train.rs)
- Medium CVE: [CVE redacted] (package-lock.json)
- Near-duplicate member pair (31 shared lines) (crates/brush-sort/src/kernels.rs)
- Near-duplicate member pair (61 shared lines) (crates/brush-loss/src/lib.rs)
- …and 3 more
New (11)
- Change coupling: lib.rs ↔ lib.rs (crates/brush-scan/src/lib.rs)
- Change-coupling hub: train.rs → render_aux.rs, visualize_tools.rs, eval.rs (crates/brush-train/src/train.rs)
- Duplicated block (10 lines × 2) (crates/brush-scan/src/kernels.rs)
- Duplicated block (5 lines × 2) (crates/brush-loss/src/lib.rs)
- Duplicated block (6–8 lines × 2) (crates/brush-render/src/bwd/kernels/project_backwards.rs)
- Near-duplicate member pair (54 shared lines) (crates/brush-loss/src/lib.rs)
- Off the main sequence: brush-async
- Off the main sequence: brush-cube
- Off the main sequence: lpips
- Off the main sequence: rrfd
- Redundant factory methods for creating a RunningProcess. The first method likely defaults to default_device(), while the second allows explicit device selection. This creates two entry points for the same logical operation (starting a training process), forcing users to guess which one to use or duplicate logic to handle device selection.
Changes since last survey
- 3 commits — 3 feature/other, 0 fixes
By area
- crates/brush-render — 3 commits
Notable commits
- change: Improve training efficiency (#554)
- change: Let burn fuse the training step, and cubecl do the scans (#546)
- change: Let burn generate the Fusion plumbing (#553)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
ArthurBrussee/brush was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 6378a76add3b93501abb55c2dc08d71688537679 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.