A production-capable Monte Carlo path tracer written in Mojo, designed for high-end light transport simulation. Gonzales renders complex scenes — including Disney's Moana Island and all 32 Bitterli benchmark scenes — with GPU-accelerated wavefront path tracing and an à-trous wavelet denoiser.
📖 Read the Gonzales Book for detailed documentation with annotated source code.
The renderer is written entirely in Mojo (~7,800 lines) and organized into focused modules:
| Module | Lines | Responsibility |
|---|---|---|
parsing.mojo |
1,959 | PBRT-v4 scene parser — geometry, materials, lights, textures |
gpu.mojo |
1,294 | GPU kernels: wavefront path tracing, à-trous denoiser, film |
shading.mojo |
770 | Material shading — diffuse, coated, conductor, dielectric |
bvh.mojo |
535 | BVH construction (SAH) and traversal |
pipeline.mojo |
457 | Batch and interactive rendering pipelines |
rendering.mojo |
407 | CPU tile renderer, film accumulation, bilateral denoiser |
ply.mojo |
316 | PLY mesh loader |
sampling.mojo |
173 | Z-Sobol sampler with Owen scrambling |
geometry.mojo |
191 | Ray, intersection, path state structs |
transform.mojo |
— | 4×4 matrix math |
rng.mojo |
— | PCG32 random number generator |
postprocess.mojo |
— | Joint bilateral denoiser (CPU) |
viewer.mojo |
— | Interactive Vulkan viewer bridge |
External C/C++ libraries (OpenImageIO, Ptex, Vulkan) are called via Mojo's C FFI — not reimplemented.
- Wavefront GPU path tracing — Batches 8 samples per bounce loop; NVIDIA GPU via Mojo's GPU API
- À-trous wavelet denoiser — Variance-adaptive 5-pass GPU denoiser (Dammertz 2010)
- Veach-style MIS — Power heuristic balancing NEE and BSDF sampling
- Pure Mojo BVH — SAH construction and traversal, no Embree dependency
- Z-Sobol sampling — Low-discrepancy sequences for fast convergence
- Russian roulette — Unbiased path termination for efficiency
- PBRT-v4 format — Full scene file compatibility
- Ptex & OpenImageIO — C FFI interop for professional texture and image handling
- Interactive viewer — GPU-accelerated real-time preview with progressive refinement
| Version | Resolution | SPP | Time | Notes |
|---|---|---|---|---|
| v0.0 (2021) | 2048×858 | 64 | 26h | GCE 8 CPU, 64 GB |
| v0.1 (2023) | 1920×800 | 64 | 78 min | Threadripper 1920X, with Embree |
| v0.2 (2026) | — | — | — | ARC cleanup, Embree removed |
| v0.3 (2026) | — | — | — | Release Notes |
Benchmark: Bitterli bathroom scene, 1024×1024, 64 spp. Hardware: AMD Ryzen 9 7950X (24 cores), NVIDIA RTX 3060 12 GB.
| Renderer | Mode | Wall time | Notes |
|---|---|---|---|
| Gonzales | GPU | 6.9s | Wavefront path tracing + à-trous denoiser |
| pbrt-v4 | GPU (OptiX) | 5.4s | Hardware RT cores |
| Embree pathtracer | CPU | 11.0s | Hardware AVX2 BVH, no textures/materials |
| Gonzales | CPU | 29.9s | Full materials and textures |
| pbrt-v4 | CPU | 53.2s | Full materials and textures |
Gonzales CPU is 1.8× faster than pbrt CPU. Gonzales GPU trails pbrt GPU by 1.3× — the gap is OptiX RT cores, which are inaccessible outside of OptiX. Embree's CPU number is not directly comparable since the benchmark scene contains no texture lookups or material evaluation (geometry traversal only).
| Project | Lines (own code) |
|---|---|
| Gonzales | ~7,800 |
| pbrt-v4 | ~84,000 (excluding bundled data tables and third-party libs) |
| Embree kernel | ~96,000 (BVH/traversal only, no rendering) |
| Dependency | Description | Install (Arch) |
|---|---|---|
Mojo (via uv) |
Compiler; GPU target requires --target-accelerator sm_XX |
uv run mojo |
| OpenImageIO | EXR/HDR image I/O | pacman -S openimageio |
| Ptex | Per-face texture mapping (Disney) | pacman -S ptex |
| Vulkan | Interactive viewer | pacman -S vulkan-icd-loader |
| Loupe | EXR image viewer (for make view_release) |
pacman -S loupe |
For GPU rendering, set --target-accelerator to match your GPU's compute
capability (e.g. sm_86 for RTX 3060, sm_89 for RTX 4090).
make debug # debug build
make release # optimized release build- Download scenes from Bitterli (PBRT-v4 format) or pbrt-v4-scenes
- Quick test — render and view a Cornell Box:
make view_release
- Or render any scene directly:
.build/release/gonzales path/to/scene.pbrt
Physically Based Rendering: From Theory to Implementation has been an inspiration since the project was called lrt.
© Andreas Wendleder 2019–2026
