Raytracing Art

Posted 2024/11/04 by Tom F.

A couple days ago I must’ve been thinking about python haphazardly as I remember becoming curious what’s happening with Mojo. I wound up on this page and the ray tracing segment piqued my interest (I’d also recommend the matrix multiplication optimization article). I then wandered to this C++ ray tracing made simple course.

If you clone this repo and go to the homework_assignment branch, there’s an interesting problem to solve: given some environment map, or in other terms a spherical image, project it onto the background instead of some hard coded color. The solution only requires an additional six lines of code!

To first understand how to approach the problem, we need to think in spherical coordinates. We have a camera which is some reference point in front of the scene, and a set of rays (vectors) which each extend up until the plane of view of our image. If a ray does not hit our scene or doesn’t reflect or refract through too many levels of recursion, then we draw one pixel of the background (envmap) by calculating two angles: the pitch and the yaw of the ray. The following snippet is in the function cast_ray and the vector is dir which is modeled in rectangular coordinates:

if (depth > RECURSION_DEPTH || !scene_intersect(orig, dir, spheres, point, N, material)) {
    float theta = acosf(dir.y); // polar angle
    float phi = atan2f(-dir.z, dir.x) + M_PI; // azimuthal angle
    float u = phi / (2 * M_PI); // normalize phi to [0, 1]
    float v = theta / M_PI;     // normalize theta to [0, 1]

    // Calculate the corresponding pixel in the environment map
    int envmap_x = std::min(envmap_width - 1, static_cast<int>(u * envmap_width));
    int envmap_y = std::min(envmap_height - 1, static_cast<int>(v * envmap_height));
    return envmap[envmap_x + envmap_y * envmap_width];

    // return Vec3f(0.2, 0.7, 0.8); // hardcoded background color
}

The images can be rendered in under a second with a crappy hp laptop which is pretty impressive for their quality.

So after this I started scavenging for hdris on this nifty site and came up with another few cool renders:

I hope to next define my own signed distance functions to make shapes like dodecahedrons and tinker with the gloss of the material. The sky’s the limit here and I haven’t even touched on post processing with GIMP. Please feel free to reach out and share what you create using this technique. I could imagine this being a great desktop wallpaper generator.

📬 Reply via e-mail.
Programming · Art