Ray Tracing with Raycore
Ray Tracing in one Hour
Analougus to the famous Ray Tracing in one Weekend, this tutorial uses Raycore to do the hard work of performant ray triangle intersection and therefore get a high performing ray tracer in a much shorter time. 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.
Setup
Ready to go! We have:
Raycorefor fast ray-triangle intersectionsGeometryBasicsfor geometry primitivesColorsandImageShowfor displaying rendered images
Part 1: Our Scene, The Makie Cat
Let's create a fun scene that we'll use throughout this tutorial.
Set the camera to something better:
Part 2: Helper Functions - Building Blocks
Let's define reusable helper functions we'll use throughout:
Part 3: The Simplest Ray Tracer - Depth Visualization
We're using one main function to shoot rays for each pixel. For simplicity, we already added multisampling and simple multi threading, to enjoy smoother images and faster rendering times throughout the tutorial. Read the GPU tutorial how to further improve the performance of this simple, not yet optimal kernel.
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:
For performance type stability is a must! We can use JET to test if a function is completely type stable, which we also test in the Raycore tests for all functions.
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_lightwithshadow_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_lightfunction - works for both hard and soft shadows
Key Raycore Functions:
Raycore.BVH(meshes)- Build acceleration structureRaycore.Ray(o=origin, d=direction)- Create rayRaycore.closest_hit(bvh, ray)- Find nearest intersectionRaycore.any_hit(bvh, ray)- Test for any intersectionRaycore.reflect(wo, normal)- Compute reflection direction
Key Pattern: The compute_light function is reusable across the entire tutorial:
shadow_samples=1→ hard shadowsshadow_samples=4→ soft shadows
This shows how a well-designed function can handle multiple use cases cleanly!