Skip to content

Repository files navigation

miniRT

miniRT is a real-time GPU ray tracing engine written in C with OpenCL, born from the 42 School common core. What started as the standard miniRT project (render a few primitives with Phong shading using minilibx) grew into something closer to a miniature Blender: a full scene editor with UI, real-time selection and editing, import/export, multiple BVH acceleration structures, and six rendering modes, all in pure C with our own custom libraries for fonts, UI components, input handling, and error management.

The engine parses .rt scene files, loads Wavefront .obj meshes with .mtl material libraries, supports PBR textures, and renders on the GPU via OpenCL with progressive accumulation. The CPU side handles scene parsing, BVH construction, an interactive UI layer with font rendering and selection, and a wireframe debug visualizer.


The Original Subject

The 42 School miniRT is a standard common core project very straightforward: render spheres, planes, and cylinders with Phong shading using minilibx, the only external rendering library permitted. Scenes are defined in a .rt text format with a camera, ambient light, point lights, and primitives.

Default miniRT render


Where We Went

We went a bit too far down the rabbit hole. The result went well beyond a basic ray tracer: six render modes (five GPU: Phong, PBR with Fresnel and GGX, Monte Carlo path tracing with chromatic dispersion, normal debug, and BVH heat map; plus a CPU wireframe view), three BVH bounding shapes (AABB, Sphere, OBB with PCA), three splitting algorithms (SAH, median-primitive, median-space), full OBJ/MTL loading with PBR texture maps, a complete in-engine UI with edit panels and selection, scene import/export, depth-of-field, exposure control, and progressive accumulation rendering.


Architecture

The render pipeline goes from .rt scene file through parsing, BVH construction, GPU kernel dispatch, accumulation, and finally display through minilibx. The UI layer is drawn on top of the rendered image and feeds edits back into the scene data and camera. See docs/01-architecture.md for the full system architecture, data hierarchy, and module dependency diagram.

Custom Libraries

Six libraries built from scratch specifically for miniRT, plus minilibx-linux (the standard 42 X11 wrapper). Everything is linked as static archives into a single binary.

miniRT Library Stack

See docs/01-architecture.md for full submodule descriptions with struct definitions and API details.


Reality Check

For a C project made in 8 months by two people with an obscure graphics library and a strict norm, this is still pretty great. But if we're being honest, there are real trade-offs and unimplemented features.

Known Issues

UI performance. All UI elements (TTF font rendering, UI components, panels, sliders, color pickers) are CPU-drawn through minilibx. There is no GPU-accelerated 2D path. This absolutely destroys performance when the UI is visible. The render itself is on GPU, but every frame the UI is redrawn pixel by pixel on the CPU.

Portability. The project was developed on 42 campus iMacs with self-compiled, somewhat wanky OpenCL packages. Portability is a real issue. The build system has machine-ID detection to switch compilers between known campus machines and everything else, which should tell you something.

Obscure C paradigms. Some parts of the codebase use abusive patterns to mimic OOP in C, notably in mlxui for component polymorphism and in mlx_wrapper for key/mouse hook actions. This can cause compilation issues on certain compiler versions. It works on campus because the compiler is old enough to let it slide.

Norminette constraints. The 42 norm enforces a single coding style (max 25 lines per function, no for loops, specific indentation, etc.). Great for learning discipline, disabling at 487 source files across the project and its submodules.

What We'd Change

If we could redo it from scratch, a lot would change. The architecture would be cleaner, the UI would not be CPU-drawn, and we'd use a proper graphics abstraction instead of minilibx.

What We Got Out of It

In any case, we had what we wanted: insight into creating big projects with multiple moving parts, needing clean separation and modularisation. It was learning how to engineer and architect from scratch big codebases, and honestly, we think we did good.

Notes on Design Scope

The project focuses on a streamlined set of features.

Acceleration structures. The renderer uses AABB, Sphere, and OBB bounding volumes with SAH, median-primitive, and median-space splitting. A single binary tree (BVH_ARITY=2) is used. BVH4/BVH8 (quad/octree branching) and DOP shapes are not implemented. A full UI for on-the-fly BVH type selection is not included - the BVH system remains simpler by design.

Scene editing. Basic property editing is available (position, rotation, scale, material assignment). A simplified scene list is provided, though not every object type is selectable in the hierarchy UI. A world settings panel for global settings like ambient light is not included.

Camera and navigation. The camera uses unified player/viewport navigation. Separate dissociated camera movement (like Blender's camera object vs. viewport) is not provided. Grid floor display, world-anchor rotation, and transform gizmo arrows are not implemented.

Textures. PPM and PFM texture formats are supported. PNG texture parsing is not included.


Prerequisites

Dependency Notes
OpenCL (1.2+, target 3.0) libOpenCL.so.1, GPU runtime
X11 development headers Windowing via minilibx
gcc (12 or 14) Or compatible C compiler
GNU Make Build system

|libXtst is bundled inside lib/minilibx-linux/local_xtst/ and does not |need to be installed separately. See docs/02-build-system.md for details on the XTEST build flag.

On Debian/Ubuntu:

sudo apt install mesa-opencl-icd opencl-headers libxext-dev \
                 libx11-dev gcc-12 make

Quick Start

# Clone, then initialize all submodules (this may take a while due to
# minirt-assets containing several gigabytes of meshes and textures)
git clone <repository-url> minirt && cd minirt && git submodule init && git submodule sync && git submodule update --remote

# Build
make

# Run
./miniRT minirt-assets/42.rt

Render Modes

miniRT supports 6 render modes switched via keyboard:

Mode Key Description
Wireframe 1 CPU rasterized debug view: BVH boxes, object outlines, light positions
Phong 2 GPU Phong shading (ambient + diffuse + specular + emissive + shadows)
PBR 3 GPU physically based rendering (Fresnel, reflection, refraction, bounces)
Monte Carlo 4 GPU path tracing (GGX sampling, chromatic dispersion, progressive accumulation)
Normal Debug - GPU normal visualization (surface normals mapped to RGB)
Heat Map = GPU BVH traversal depth heat map (10 color palettes)

See docs/04-render-modes/ for detailed descriptions of each mode's kernel logic, formulas, and pipeline diagrams.


Key Bindings

Key Action
W / A / S / D Movement (forward / left / backward / right)
Space / Shift Move up / down
1-4 / - / = Switch render mode (wireframe / Phong / PBR / Monte Carlo / normal debug / heat map)
M Cycle UI mode (full, minimal, hidden)
V Toggle BVH debug overlay
F11 / F12 Export scene to .rt / schedule render to PPM

See docs/07-camera-and-interaction.md for the full key binding table, camera model details, and depth of field mechanics.


Build Options

Flag Default Description
WIDTH 1920 Window width (or MAX_WIDTH if FULLSCREEN=1)
HEIGHT 1080 Window height (or MAX_HEIGHT if FULLSCREEN=1)
FULLSCREEN 0 Use full screen resolution (detected via xrandr)
FAST auto Set by make fast; adds -Ofast -march=native -mtune=native -msse3
DEBUG_LVL 0 Tiered debug level (0 = release, 1-5 = increasing subsystem debug)

See docs/02-build-system.md for the full build flags reference, sanitizer targets, and environment variables.


Documentation

File Description
docs/00-project-overview.md Project overview, feature comparison with the 42 subject
docs/01-architecture.md System architecture, data hierarchy (t_data, t_scene), module dependency diagram
docs/02-build-system.md Build system, Makefile targets, flags, sanitizers, compiler selection
docs/03-scene-format.md .rt scene format, MTL material format, OBJ mesh format, parser architecture
docs/04-render-modes/ Render mode deep dives: wireframe, Phong, PBR, Monte Carlo, normal debug, heat map
docs/05-bvh.md BVH construction, bounding volumes (AABB/Sphere/OBB), splitting algorithms, GPU traversal
docs/06-opencl-integration.md OpenCL lifecycle, kernel embedding, buffer architecture, frame loop sequence
docs/07-camera-and-interaction.md Camera model, depth of field, exposure, key bindings, BVH debug controls
docs/08-materials-and-textures.md Material system, texture atlas, normal mapping, Fresnel/Schlick, refraction
docs/09-asset-catalog.md Scene files, OBJ meshes, MTL materials, textures, skyboxes
docs/10-ui-system.md UI hierarchy tree, edit panels, selection system, color theme, font rendering

Authors

Aubry Richard Jaurel (jaubry--) and Bellissant Pablo (pabellis), 42 Lyon.

About

Real time GPU path tracing written in C

Resources

Stars

6 stars

Watchers

1 watching

Forks

Contributors

Languages