Build Status Build status Codacy Badge CodeFactor

Overview

rayray is a “baby” raytracer I’ve been working on in my spare time. By “baby”, I mean that it is small in size and relatively simple in nature; it doesn’t do complex things.

My motivation was my interest in 3D graphics. Due to this, I got a few books that describe how to write a ray tracer. Namely Ray Tracing from the Ground Up and the mini series Ray Tracing in One Weekend. I’ve particularly been enjoying the first book since it is much more in depth and provides much of the mathematical background for the concepts. It’s still a work in progress and I’d like to add more features (like support for different image output types, mesh rendering, better lighting). Below is a sample render from the raytracer:

And the code to generate the above image:

int main(int argc, char* argv[])
{
    using vec3 = rayray::vector<double, 3>;
    using uchar = unsigned char;

    rayray::pinhole_camera camera;
    camera.set_eye(0, 0, 500);
    camera.set_lookat(-5, 0, 0);
    camera.set_view_plane_distance(1750.0);
    camera.compute_uvw();

    rayray::scene basic_scene;
    basic_scene.set_background_color(rayray::black());

    rayray::view_plane view_plane(1920, 1080, 1.0, 1.0);
    
    // initialize the sampler and generate the samples
    rayray::multijittered_sampler sampler(25); 
    sampler.generate_samples();

    view_plane.set_sampler(&sampler);
    basic_scene.set_view_plane(view_plane);

    rayray::ray_cast_tracer scene_tracer(&basic_scene);
    basic_scene.set_tracer(&scene_tracer);

    rayray::ambient_light amb_light;
    amb_light.set_radiance_scaling(1.0);
    amb_light.set_color({ 1.0, 1.0, 1.0 });

    basic_scene.set_ambient_light(&amb_light);

    rayray::point_light pt_light;
    pt_light.set_location({ 100, -100, 150 });
    pt_light.set_radiance_scaling(3.0);
    basic_scene.add_light(&pt_light);

    rayray::matte matte_material;
    matte_material.set_ka(0.25);
    matte_material.set_kd(0.65);
    matte_material.set_cd(1.0, 0.0, 0.0);

    rayray::matte matte_blue;
    matte_blue.set_ka(0.35);
    matte_blue.set_kd(0.55);
    matte_blue.set_cd(0.0, 0.0, 1.0);

    rayray::sphere sp1({ 10.0, -5.0, 0.0 }, 27.0);
    sp1.set_material(&matte_material);
   
    rayray::sphere sp2({ -10.0, -10.0, -50.0 }, 30.0);
    sp2.set_material(&matte_blue);

    // add objects to scene.
    basic_scene.add_object(&sp1);
    basic_scene.add_object(&sp2);

    const auto output_image = camera.render_scene(basic_scene);
    const auto ok = rayray::io::write_ppm_image(output_image, "output.ppm");

    if(!ok)
    {
        std::cout << "Could not output image." << std::endl;
        return -1;
    }

    return 0;
}

The next major milestone for rayray is to get it to the state where it can successfully render the Cornell box; a classic ray tracing engine test. Further than that I’d like to be able to save/load scenes and add the ability to render meshes.

Please feel free to check out the code on Github and let me know what you think! PR’s are also welcome if you’d like to contribute.