Skip to content

RishabhRD/mraylib

Repository files navigation

mraylib

mraylib is a C++23 pure algorithmic ray tracing library.

mraylib focuses on following:

  • Design by contract [WIP]
  • Independent of Execution Context (use Senders/Receivers)
  • Pure Algorithmic

Design by contract [WIP]

I started mraylib as an exercise of trying to write something real with what I felt is good code. Any feedbacks or contribution in this direction is highly appreciated.

Independent of Execution Context

I have seen many ray tracers that written for thread pool or single thread or cuda. However, I wanted this ray tracer to be independent of execution context. This needed a good abstraction over exeuctors. P2300 is a good proposal for the same. mraylib depends on stdexec (an implementation of P2300) algorithms for its execution.

Library assumes stdexec to be present while compilation.

Pure Algorithmic

mraylib algorithms depends on concepts (requirements) instead of depending on concrete types. For example render algorithm depends on OutputRandomAccessImage concept instead of depending on any specific image implementation. A library user can use any type that satisfies these concepts for algorithms.

A sample Program

#include "mraylib.hpp"
#include <fstream>
#include <vector>

using namespace mrl;

int main() {
  // Configure Execution Context
  auto const num_threads = std::thread::hardware_concurrency();
  auto th_pool = thread_pool{num_threads};
  auto sch = th_pool.get_scheduler();

  // Configure camera (how we look into the world)
  camera_t camera{
      .focus_distance = 10.0,
      .vertical_fov = degrees(20),
      .defocus_angle = degrees(0.0),
  };
  camera_orientation_t camera_orientation{
      .look_from = {13, 2, 3},
      .look_at = point3(0, 0, 0),
      .up_dir = direction_t{0, 1, 0},
  };

  // Defining the world
  using any_object = any_object_t<decltype(sch)>;
  std::vector<any_object> world;
  dielectric mat1(1.5);
  lambertian_t mat2(color_t{0.4, 0.2, 0.1});
  metal_t mat3(color_t{0.7, 0.6, 0.5});

  auto checker = lambertian_t{
      checker_texture{0.32, solid_color_texture{from_rgb(38, 39, 41)},
                      solid_color_texture{color_t{.9, .9, .9}}}};

  world.push_back(shape_object{sphere{1.0, point3{0, 1, 0}}, mat1});
  world.push_back(shape_object{sphere{1.0, point3{-4, 1, 0}}, mat2});
  world.push_back(shape_object{sphere{1.0, point3{4, 1, 0}}, mat3});
  world.push_back(shape_object{sphere{1000.0, point3{0, -1000, 0}}, checker});
  // Acceleration structure for handling large number of objects
  bvh_t<any_object> bvh{std::move(world)};

  // Defining Image
  aspect_ratio_t ratio{16, 9};
  auto img_width = 600;
  auto img_height = image_height(ratio, img_width);
  in_memory_image img{img_width, img_height};
  auto path = std::getenv("HOME") + std::string{"/readme.ppm"};
  std::ofstream os(path, std::ios::out);

  // Actually run the algorithm
  auto background = color_t{0.7, 0.8, 1.0};
  auto cur_time = static_cast<unsigned long>(
      std::chrono::system_clock::now().time_since_epoch().count());
  img_renderer_t renderer(camera, camera_orientation, background, sch,
                          cur_time);
  stdexec::sync_wait(renderer.render(bvh, img));
  write_ppm_img(os, img);
}

Examples

Some examples with different features can be found in examples/ directory.

Building Examples

Add stdexec to include path. (stdexec is not there in conan center, contribution for handling it through cmake would be appreciated). Then execute:

./update_package
./build

Documentation

Docs can be found in doc/ directory.

Future Goals

  • Explore more in terms of parallelism
  • Explore more in terms of acceleration structures
  • Explore more in terms of improving codebase and improving code in terms of design by contract without degrading performance
  • Performance optimizations

Any contribution in these directions are highly appreciated.

Credits

About

simple ray tracing library focusing on good code

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published