A C++17 Whitted-style ray tracer with a JSON scene format, FLTK/OpenGL viewer, BVH acceleration, cubemap support, mesh loading, and an optional neural upsampling pipeline for post-render enhancement.
The showcase above was rendered locally from scenes bundled in this repository.
- Recursive shading with emissive, ambient, diffuse, and specular terms.
- Shadows, distance attenuation, reflection, refraction, and transmissive shadow filtering.
- Built-in primitives: sphere, box, square, cylinder, cone, and linked portals.
- Triangle-mesh and OBJ-mesh rendering with barycentric interpolation, generated normals, and texture mapping.
- Scene-level BVH acceleration plus per-trimesh BVH acceleration for mesh faces.
- Cubemap environment rendering from a single face-path hint.
- Optional overlap-aware refraction and harmonic tracing demos controlled through environment variables.
- Optional Python tooling for neural upsampling and anti-aliasing experiments.
The renderer itself is a native C++ project. You will need:
- A C++17 compiler
- CMake 3.16+
- FLTK
- OpenGL / GLU
- libpng
- zlib
On first configure, CMake may fetch a local copy of GLM into third-party/glm.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"$(nproc)"This produces the main executable at build/bin/ray.
Render one of the bundled scenes:
mkdir -p out
./build/bin/ray -r 6 -w 720 assets/custom/custom4.json out/custom4.pngUseful command-line flags:
| Flag | Meaning |
|---|---|
-r <depth> |
Maximum recursion depth for reflection/refraction rays. |
-w <width> |
Output image width. Height is inferred from the camera aspect ratio. |
-j <file> |
Load renderer settings from a JSON config file. |
-c <file> |
Load a cubemap by pointing at any one of its six faces. |
With no arguments, build/bin/ray enters the FLTK graphical UI on systems with a display. Supplying an input scene and output image uses command-line render mode.
Standard custom scene:
./build/bin/ray -r 6 -w 720 assets/custom/custom4.json out/custom4.pngCubemap render:
./build/bin/ray -r 5 -w 720 \
-c assets/cubemaps/cubemap_autumn/autumn_positive_x.png \
assets/scenes/trimesh/dragon4.json \
out/cubemap_dragon.pngPortal demo:
./build/bin/ray -r 6 -w 720 assets/custom/portal_circle.json out/portal_circle.pngOverlap-aware refraction demo:
RAY_ENABLE_OVERLAP_REFRACTION=1 \
./build/bin/ray -r 7 -w 720 assets/custom/custom_overlap.json out/custom_overlap.pngHarmonic tracing demo:
RAY_ENABLE_HARMONIC_TRACING=1 RAY_HARMONIC_MODE=gyroid \
./build/bin/ray -r 7 -w 720 assets/custom/harmonic_gyroid.json out/harmonic_gyroid.pngThe -j flag lets you override render settings without changing scene files. A typical config looks like:
{
"threads": 8,
"recursion_depth": 6,
"anti_alias": true,
"supersamples": 4,
"tree_depth": 18,
"leaf_size": 8,
"filter_width": 1,
"shadows": true,
"smoothshade": true,
"backface_culling": true
}Example:
./build/bin/ray -j render.json assets/scenes/scene.json out/scene.pngScenes in this repo are primarily JSON files under assets/scenes/ and assets/custom/. The parser also supports legacy .ray input files, but the bundled content is JSON-first.
Supported top-level object types include:
cameraambient_lightpoint_lightdirectional_lightsphereboxsquarecylinderconeportaltri_meshobj_meshmaterialtransform
The full format reference lives in src/parser/jsonformat.md.
Useful scene collections:
assets/scenes/: baseline scenes for standard rendering features.assets/scenes/trimesh/: triangle-mesh stress tests and demos.assets/scenes/objmesh/: OBJ-based scenes and texture-mapped assets.assets/custom/: custom demos for portals, overlap-aware refraction, harmonic tracing, and more experimental scenes.
For a quick build-and-render pass across the main feature demos, run:
./build.shThe script compiles the renderer and writes a focused set of showcase outputs under renders/, including:
renders/showcase/custom4.pngrenders/cubemap/dragon4_autumn.pngrenders/portal/portal_rect.pngrenders/portal/portal_circle.pngrenders/overlap/custom_overlap.pngrenders/harmonic/harmonic_riemann.pngrenders/harmonic/harmonic_gyroid.png
The Python side of the repo is optional. The core renderer does not need PyTorch.
The repo includes:
ec_neuralnet.py: training and evaluation for an EDSR/RCAN-style upsampler.nn_infer.py: inference script for image folders or for ray-traced scene renders.anti_alias_nn.py: a simpler SRCNN-style anti-aliasing experiment.download_data_neuralnet.py: downloader for the DIV2K training and validation sets.our_model.pth: bundled pretrained weights.nn_inputs/andnn_outputs/: sample input images and generated outputs.
To set up the optional Python environment:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtNote: requirements.txt covers the optional neural tooling only. The core C++ renderer does not require any Python packages.
Render a low-resolution scene, upscale it with the bundled network, and save a comparison strip:
python3 nn_infer.py \
--scene assets/scenes/trimesh/dragon4.json \
--output nn_demo \
--model our_model.pth \
--render-width 320 \
--render-depth 5 \
--render-reference \
--save-comparisonThis script can also operate directly on image files or directories through --input.
python3 download_data_neuralnet.pyThis downloads and extracts:
DIV2K/DIV2K_train_HRDIV2K/DIV2K_valid_HR
| Path | Purpose |
|---|---|
src/ |
Core renderer, parser, scene graph, UI, geometry, and file I/O. |
assets/scenes/ |
Baseline JSON scenes and textures. |
assets/custom/ |
Feature-specific demos and custom showcase scenes. |
assets/cubemaps/ |
Cubemap datasets used by -c. |
build.sh |
Build + demo-render script for the main showcase scenes. |
ec_neuralnet.py, nn_infer.py, anti_alias_nn.py |
Optional ML / post-processing pipeline. |
our_model.pth |
Bundled pretrained upsampling weights. |
- The bundled showcase image in this README was generated with the current repo state using
build/bin/ray. - Many bundled scenes are intentionally small and fast to render, which makes them useful for debugging and iteration on new features.
