How to Contribute to the Brush Project: A Complete Guide for 3D Gaussian Splat Developers
To contribute to the Brush project, fork the repository, install Rust ≥ 1.88 with Android and WASM targets, run cargo test --all to verify your setup, then submit changes following the conventional commit format and the upstream CI workflow.
Brush is a Rust-first, cross-platform 3D reconstruction engine that implements Gaussian splatting using the Burn machine learning framework. Whether you want to optimize GPU kernels, extend the desktop UI, or improve the WebAssembly demo, understanding the crate structure and contribution workflow is essential. This guide walks you through the exact steps needed to modify the codebase at github.com/ArthurBrussee/brush and submit a successful pull request.
Understanding the Brush Architecture
Brush is organized as a Cargo workspace with separate crates handling distinct stages of the 3D reconstruction pipeline. Before contributing, identify which crate aligns with your goal:
- brush-render – Core forward rendering kernels located in
crates/brush-render/src/kernels/map_gaussians.rshandling rasterization and splat mapping. - brush-render-bwd – Back-propagation kernels for gradient-based training in
crates/brush-render-bwd/src/kernels/rasterize_backwards.rs. - brush-loss – Loss functions and training utilities in
crates/brush-loss/src/lib.rs. - brush-app – Native desktop viewer and trainer built with WGPU, with UI code in
apps/brush-app/src/ui/app.rs. - brush-js – WebAssembly front-end using Next.js, documented in
apps/brush-js/README.md. - brush-cli – Command-line interface for training and conversion in
apps/brush-cli/src/lib.rs. - brush-rerun – Integration with the Rerun visualization tool.
The workspace configuration resides in the root Cargo.toml, which defines shared dependencies and Rust version requirements (≥ 1.88) across all crates.
Setting Up Your Development Environment
1. Fork and Clone the Repository
Start by creating a personal fork via the GitHub UI, then clone it locally:
git clone https://github.com/<your-username>/brush.git
cd brush
2. Install the Rust Toolchain
Brush requires Rust ≥ 1.88. Install the latest stable toolchain and add required compilation targets:
rustup update stable
rustup target add aarch64-linux-android # Required for Android builds
rustup target add wasm32-unknown-unknown # Required for WASM builds
Install additional platform-specific tools:
cargo install cargo-ndk # Android cross-compilation helper
cargo install wasm-pack # WASM packaging utility
cargo install cargo-bloat # Optional: binary size analysis
cargo install rerun-cli # Optional: visualization support
The Contribution Workflow
Running the Test Suite
Verify your environment by executing the full test suite locally. Passing tests locally prevents CI failures on your pull request:
cargo test --all
This command mirrors the GitHub Actions workflow defined in .github/workflows/ci.yml.
Making Your Changes
Select the appropriate crate based on your contribution type:
- New GPU kernels → Modify
crates/brush-renderorcrates/brush-render-bwd. - New loss terms → Add code to
crates/brush-loss. - UI modifications → Edit files under
crates/brush-app/src/ui/. - Web demo improvements → Work within
apps/brush-js.
Before committing, enforce the project’s code style:
cargo fmt
cargo clippy -- -D warnings
Every new public API requires unit or integration tests in the same crate. Reference existing test patterns, such as those in crates/brush-loss/tests/reference.rs.
Building and Verifying Across Platforms
Validate your changes on the target platform:
| Platform | Build Command |
|---|---|
| Desktop (Linux/macOS/Windows) | cargo run --release |
| Web (WASM) | npm run dev (inside apps/brush-js) |
| Android | cargo ndk -t arm64-v8a -o crates/brush-app/app/src/main/jniLibs/ build --release then ./gradlew installDebug |
Ensure the application launches correctly and new functionality behaves as expected on your target platform.
Committing and Submitting Your Changes
Create a feature branch using conventional commit naming:
git checkout -b feature/my-new-kernel
git add .
git commit -m "feat(render): implement fast Gaussian splat kernel"
git push origin feature/my-new-kernel
Open a pull request against the main branch. Fill out the auto-generated PR template completely. The CI pipeline will run cargo test --all across all supported targets. Respond promptly to reviewer feedback, which may involve updating documentation or adjusting code in files like Cargo.toml or kernel implementations.
Code Example: Adding a New Rendering Kernel
The following example demonstrates adding a custom GPU kernel to the brush-render crate, following the pattern established in crates/brush-render/src/kernels/map_gaussians.rs:
// File: crates/brush-render/src/kernels/my_custom_kernel.rs
//! A simple example kernel that multiplies splat colour by a constant factor.
use wgpu::util::DeviceExt;
/// Entry point called by the CPU side.
pub fn run_my_kernel(
device: &wgpu::Device,
queue: &wgpu::Queue,
gaussian_buffer: &wgpu::Buffer,
output_buffer: &wgpu::Buffer,
factor: f32,
) {
// Load the shader (WGSL) from the same directory.
let shader = device.create_shader_module(&wgpu::ShaderModuleDescriptor {
label: Some("my_custom_kernel"),
source: wgpu::ShaderSource::Wgsl(include_str!("my_custom_kernel.wgsl").into()),
});
// Create a pipeline layout and compute pipeline.
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("my_custom_kernel_layout"),
bind_group_layouts: &[],
push_constant_ranges: &[],
});
let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
label: Some("my_custom_kernel_pipeline"),
layout: Some(&pipeline_layout),
module: &shader,
entry_point: "main",
});
// Encode commands.
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("my_custom_kernel_encoder"),
});
{
let mut compute_pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label: Some("my_custom_kernel_pass"),
});
compute_pass.set_pipeline(&pipeline);
compute_pass.set_bind_group(0, &gaussian_buffer.create_bind_group(&device), &[]);
compute_pass.set_bind_group(1, &output_buffer.create_bind_group(&device), &[]);
compute_pass.set_push_constants(0, bytemuck::bytes_of(&factor));
compute_pass.dispatch_workgroups( (gaussian_buffer.size() / 256) as u32, 1, 1);
}
queue.submit(Some(encoder.finish()));
}
After creating the kernel file, expose the function in crates/brush-render/src/lib.rs and write a unit test verifying the output buffer values. Update the crate-level documentation using /// comments and add a minimal example to the examples/ folder if applicable.
Summary
- Fork and clone the repository from
github.com/ArthurBrussee/brush, then install Rust ≥ 1.88 with Android and WASM targets. - Target the correct crate: use
brush-renderfor GPU kernels,brush-appfor UI changes, andbrush-jsfor web improvements. - Validate locally by running
cargo test --all,cargo fmt, andcargo clippy -- -D warningsbefore submitting. - Build per platform using
cargo run --releasefor desktop,npm run devfor WASM, orcargo ndkfor Android. - Follow conventions: use conventional commit messages, fill out the PR template, and ensure CI passes in
.github/workflows/ci.yml.
Frequently Asked Questions
What Rust version is required to contribute to Brush?
Brush requires Rust 1.88 or newer as specified in the root Cargo.toml. Install it via rustup update stable and ensure you add targets for aarch64-linux-android and wasm32-unknown-unknown if you plan to build for mobile or web platforms.
Which crate should I modify to add a new rendering kernel?
Add new forward rendering kernels to crates/brush-render/src/kernels/ following the pattern in map_gaussians.rs. For back-propagation kernels used during training, use crates/brush-render-bwd/src/kernels/ instead, referencing rasterize_backwards.rs for implementation details.
How do I build the web demo locally?
Navigate to apps/brush-js and run npm run dev. This requires wasm-pack to be installed and the wasm32-unknown-unknown target to be available. The README at apps/brush-js/README.md contains additional build instructions for the Next.js front-end.
How do I run the full CI pipeline locally before submitting a PR?
Execute cargo test --all && cargo bench && npm run build to replicate the GitHub Actions workflow defined in .github/workflows/ci.yml. Running these commands ensures your changes pass formatting, linting, and testing requirements before reviewers examine your pull request.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →