Interactive Rust SDF Path Tracer

Loading WASM...

Rust Ray Tracer & SDF Engine

A ray tracer written in Rust, capable of rendering Constructive Solid Geometry (CSG).

Ferris the Crustacean

Unlike using triangle meshes, this engine is a Ray Marcher using Signed Distance Fields (SDFs). This allows for:


Ray Tracer Instructions

Modify the scene by typing into the scene editor box.


1. Global Settings

The following details relate to the initial values that can be edited.

Rendering resolution

You can change the output resolution, and the sampling quality.

1 sample Samples = 1

32 samples Samples = 32

"render": {
        "width": 640,   // 640 pixels across
        "height": 480,  // 480 pixels high
        "samples": 2    // each final pixel colour is made from 4 (2 by 2) subpixels
        }

Sky (background)

These values change the colours of the sky, the horizon, and also affect the mist/fog that forms in the far distance. Both are RGB (Red Green Blue) values.

Red horizon A red horizon with a purple sky.

"sky": {
        "horizon": [0.8, 0.8, 1.0], // A pale blue horzizon
        "zenith": [0.0, 0.0, 1.0]   // A deep blue sky above 
        }

Camera Control

You can move the camera anywhere in 3D space.

My mascot This animation was made by changing the x position of the camera.

"camera": {
        "position": [0.0, 5.0, 10.0], // High up and pulled back
        "look_at": [0.0, 0.0, 0.0],   // Looking at the center
        "fov": 45.0
        }

Lighting (brightness)

To change the scene brightness, adjust the intensity value.

High intensity Intensity of 1.5

Low intensity Intensity of 0.5

"light": {
        "direction": [4.0, 2.0, 2.0], // The light comes from the right, above and in front of the scene.
        "intensity": 1.0
        }

2. Creating Objects

Objects are defined in the objects list. The renderer processes this list in order (see "The Stack Logic" below).

Common Properties

Every object shares these fields:

Textures The ground plane uses 1.0 reflectivity and the Bumpy texture. The first sphere uses Solid. The second is Solid with 1.0 reflectivity. The third uses Streaky. The last uses Checkered.

Sphere

Defined by a single radius parameter.

{
        "primitive": "Sphere",
        "position": [0.0, 1.0, 0.0],   // The centre of the sphere is a bit above the centre of the scene
        "parameters": [1.0],           // The total height and width of a sphere will be double the radius
        "color": [1.0, 0.1, 0.1],      // Red
        "reflectivity": 0.5,           // Partially reflective  
        "texture_type": "Solid"        // Colour only, no pattern
        }

Cube

Defined by "half-extents" (distance from center to edge).

{
        "primitive": "Cube",
        "position": [2.0, 0.5, 0.0],   // To the right, and a bit above the centre
        "parameters": [0.7, 0.7, 0.7], // Size X, Y, Z
        "color": [0.2, 0.2, 1.0],      // Blue
        "reflectivity": 0.0,
        "texture_type": "Solid"
        }

Cylinder

Defined by the total height and the radius.

{
        "primitive": "Cylinder",
        "position": [-2.0, 1.0, 0.0], // To the left, and a bit above the centre
        "parameters": [2.0, 0.5],     // Two units tall, diameter of 1
        "color": [0.2, 0.8, 0.2],     // A shade of green
        "reflectivity": 0.2,
        "texture_type": "Solid"
        }

Flat Plane (Floor/Wall)

Defined by a Normal Vector (the direction it faces).

Warning: If a plane's position and parameters are such that the camera would show the reverse side of plane (like if a plane intended to be the ground has a negative y parameter), the scene will be completely dark.

Tilted plane The parameters [0.6, 1.0, 0.5] have tilted the chequered plane.

{
        "primitive": "Plane",
        "position": [0.0, -1.0, 0.0],  // A bit below the centre
        "parameters": [0.0, 1.0, 0.0], // Normal pointing UP
        "color": [0.8, 0.8, 0.8],      // A light grey
        "reflectivity": 0.1,
        "texture_type": "Checkered"
        }

3. Advanced Modeling: The "Stack" System

This engine uses a unique Stack-based approach to modeling. The scene is built layer-by-layer, starting from empty space. The order of objects in the JSON list matters significantly.

Each object applies an Operation to the world that exists before it in the list.

Operations

Sphere and Cube subtract A sphere is cut into by a cube using Subtract.

Sphere and Cube intersect Using Intersect, only the parts of the sphere and cube that overlap are visible. The ground isn't in this area, so it is now gone as well.

Blending (Smooth Transitions)

You can set a blend value (e.g., 0.5) to smooth the transition between the new object and the existing world.

Spheres smooth union A red sphere and a yellow sphere blended into each other.

Spheres smooth subtract Using Subtract and a high blend value, an invisible cylinder makes a hole in the ground with a rounded edge.

smooth intersect A cube, sphere, cylinder and plane inside an Intersect sphere, which has removed all object parts that are outside of it. Edges are smooth because of blending, and have also adopted the material properties of the sphere.

Important: Preventing Accidental Deletion

If you use Intersect or Subtract, be careful with your ordering.


4. Limitations

There are several common 3D modelling features that are unavailable here.