Ray Tracing with Raycore

Ray Tracing with Raycore: Building a Real Ray Tracer

In this tutorial, we'll build a simple but complete ray tracer from scratch using Raycore. We'll start with the absolute basics and progressively add features until we have a ray tracer that produces beautiful images with shadows, materials, and reflections.

By the end, you'll have a working ray tracer that renders at interactive speeds!

Setup

Ready to go! We have:

  • Raycore for fast ray-triangle intersections

  • GeometryBasics for geometry primitives

  • Colors and ImageShow for displaying rendered images

Part 1: Our Scene, The Makie Cat

Let's create a fun scene that we'll use throughout this tutorial.

BVHAccel: Triangles: 19866 BVH nodes: 40859 (20429 interior, 20430 leaves) Bounds: Float32[-5.0, -1.5, -2.0] to Float32[5.0, 3.5, 8.01] Max prims: 1 per leaf Avg prims: 0.97 per leaf

Scene created! Cat model, room geometry, decorative spheres, and BVH for fast ray traversal.

Part 2: Helper Functions - Building Blocks

Let's define reusable helper functions we'll use throughout:

to_rgb (generic function with 1 method)

Part 3: The Simplest Ray Tracer - Depth Visualization

depth_kernel (generic function with 1 method)

First render! Depth visualization shows distance to surfaces. Much faster with threading and smoother with multi-sampling!

Part 5: Lighting with Hard Shadows

Let's add lighting and shadows using a reusable lighting function:

Hard shadows working! Scene has realistic lighting with sharp shadow edges.

Part 6: Soft Shadows

Now let's make shadows more realistic by sampling the light as an area light:

Soft shadows! Much more realistic with smooth penumbra edges.

Part 7: Materials and Multiple Lights

Time to add color and multiple lights:

Colorful scene with soft shadows from multiple lights! Each object has its own material.

Part 8: Reflections

Add simple reflections for metallic surfaces:

Summary

We built a complete ray tracer with:

Core Features:

  • BVH acceleration for fast ray-scene intersections

  • Perspective camera with configurable FOV

  • Smooth shading from interpolated normals

  • Multi-light system with distance attenuation

  • Soft shadows using area light sampling (via compute_light with shadow_samples)

  • Material system (base color, metallic, roughness)

  • Reflections with optional roughness

  • ACES tone mapping for HDR

Performance:

  • Multi-threading for parallel rendering (introduced early!)

  • Multi-sampling for anti-aliasing (introduced early!)

  • Type-stable kernels for optimal performance

  • Modular, reusable compute_light function - works for both hard and soft shadows

Key Raycore Functions:

  • Raycore.BVHAccel(meshes) - Build acceleration structure

  • Raycore.Ray(o=origin, d=direction) - Create ray

  • Raycore.closest_hit(bvh, ray) - Find nearest intersection

  • Raycore.any_hit(bvh, ray) - Test for any intersection

  • Raycore.reflect(wo, normal) - Compute reflection direction

Key Pattern: The compute_light function is reusable across the entire tutorial:

  • shadow_samples=1 → hard shadows

  • shadow_samples=4 → soft shadows

This shows how a well-designed function can handle multiple use cases cleanly!

Happy ray tracing!