Skip to content
14 changes: 0 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,13 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

if(NOT OUTPUT_WIDTH)
message(STATUS "Setting output width to 800 as none was specified.")
set(OUTPUT_WIDTH "800" CACHE
STRING "Image width in pixel" FORCE)
endif()

if(NOT OUTPUT_HEIGHT)
message(STATUS "Setting output height to 480 as none was specified.")
set(OUTPUT_HEIGHT "480" CACHE
STRING "Image height in pixel" FORCE)
endif()


set(SYCL_RT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(SYCL_RT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

add_executable(sycl-rt ${SYCL_RT_SRC_DIR}/main.cpp)

target_include_directories(sycl-rt PRIVATE ${SYCL_RT_INCLUDE_DIR})
target_compile_definitions(sycl-rt PRIVATE OUTPUT_WIDTH=${OUTPUT_WIDTH})
target_compile_definitions(sycl-rt PRIVATE OUTPUT_HEIGHT=${OUTPUT_HEIGHT})

# This is a SYCL program
if ("${SYCL_CXX_COMPILER}" STREQUAL "")
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,16 @@ This creates the executable.

Now you can run the path tracer with:
```sh
time ./sycl-rt
time ./sycl-rt 800 480 50 100
```
This results in the image `out.png` produced by the path tracer.
This results in the image ``out.png`` produced by the path tracer.

Parameters to the executable are

+ The output image width (here 800)
+ The output image height (here 480)
+ The maximum bouncing depth of the ray (here 50)
+ The number of samples per pixel (here 100)


## Bibliography
Expand Down
4 changes: 2 additions & 2 deletions include/box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class box {
}

/// Compute ray interaction with the box
bool hit(auto& ctx, const ray& r, real_t min, real_t max, hit_record& rec,
bool hit(const ray& r, real_t min, real_t max, hit_record& rec,
material_t& hit_material_type) const {
hit_record temp_rec;
material_t temp_material_type;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the feeling that if we remove the std::monostate from the material it will always create a sphere here even when there is no intersection.

Expand All @@ -36,7 +36,7 @@ class box {
for (const auto& side : sides) {
if (dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, min, closest_so_far, temp_rec,
return arg.hit(r, min, closest_so_far, temp_rec,
temp_material_type);
},
side)) {
Expand Down
4 changes: 3 additions & 1 deletion include/build_parameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ constexpr bool use_sycl_compiler = USE_SYCL_COMPILER;
constexpr bool use_sycl_compiler = false;
#endif

constexpr int output_width = OUTPUT_WIDTH;
/*constexpr int output_width = OUTPUT_WIDTH;
constexpr int output_height = OUTPUT_HEIGHT;
constexpr int samples = SAMPLES;
constexpr int depth = DEPTH;//*/
} // namespace buildparams

#endif // BUILD_PARAMETERS_HPP
2 changes: 1 addition & 1 deletion include/camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class camera {
return { origin + offset,
lower_left_corner + s * horizontal + t * vertical - origin -
offset,
rng.float_t(time0, time1) };
rng.real(time0, time1) };
}
};

Expand Down
13 changes: 6 additions & 7 deletions include/constant_medium.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "box.hpp"
#include "material.hpp"
#include "rtweekend.hpp"
#include "sphere.hpp"
#include "texture.hpp"
#include "visit.hpp"
Expand All @@ -25,24 +26,21 @@ class constant_medium {
, neg_inv_density { -1 / d }
, phase_function { isotropic_material { a } } {}

bool hit(auto& ctx, const ray& r, real_t min, real_t max, hit_record& rec,
bool hit(const ray& r, real_t min, real_t max, hit_record& rec,
material_t& hit_material_type) const {
auto& rng = ctx.rng;
hit_material_type = phase_function;
material_t temp_material_type;
hit_record rec1, rec2;
if (!dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, -infinity, infinity, rec1,
temp_material_type);
return arg.hit(r, -infinity, infinity, rec1, temp_material_type);
},
boundary)) {
return false;
}

if (!dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, rec1.t + 0.0001f, infinity, rec2,
return arg.hit(r, rec1.t + 0.0001f, infinity, rec2,
temp_material_type);
},
boundary)) {
Expand All @@ -62,7 +60,8 @@ class constant_medium {
/// Distance between the two hitpoints affect of probability
/// of the ray hitting a smoke particle
const auto distance_inside_boundary = (rec2.t - rec1.t) * ray_length;
const auto hit_distance = neg_inv_density * sycl::log(rng.float_t());
auto rng = LocalPseudoRNG { toseed(r.direction(), r.origin()) };
const auto hit_distance = neg_inv_density * sycl::log(rng.real());

/// With lower density, hit_distance has higher probabilty
/// of being greater than distance_inside_boundary
Expand Down
23 changes: 23 additions & 0 deletions include/hit_record.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef HIT_RECORD_HPP
#define HIT_RECORD_HPP

#include "rtweekend.hpp"

class hit_record {
public:
real_t t; //
point p; // hit point
vec normal; // normal at hit point
bool front_face; // to check if hit point is on the outer surface
/*local coordinates for rectangles
and mercator coordintes for spheres */
real_t u;
real_t v;

// To set if the hit point is on the front face
void set_face_normal(const ray& r, const vec& outward_normal) {
front_face = dot(r.direction(), outward_normal) < 0;
normal = front_face ? outward_normal : vec {} - outward_normal;
}
};
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing end-of-line.
Yes, this is good to have this in its own file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious... An IDE configuration bug?

25 changes: 5 additions & 20 deletions include/hitable.hpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,11 @@
#ifndef HITTABLE_H
#define HITTABLE_H

#include "box.hpp"
#include "constant_medium.hpp"
#include "ray.hpp"
#include "rtweekend.hpp"
#include "vec.hpp"

class hit_record {
public:
float t; //
point p; // hit point
vec normal; // normal at hit point
bool front_face; // to check if hit point is on the outer surface
/*local coordinates for rectangles
and mercator coordintes for spheres */
float u;
float v;

// To set if the hit point is on the front face
void set_face_normal(const ray& r, const vec& outward_normal) {
front_face = dot(r.direction(), outward_normal) < 0;
normal = front_face ? outward_normal : vec {} - outward_normal;
}
};
#include "sphere.hpp"
#include "triangle.hpp"

using hittable_t = std::variant<sphere, triangle, constant_medium, box, xy_rect>;
#endif
50 changes: 23 additions & 27 deletions include/material.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <iostream>

#include "hitable.hpp"
#include "hit_record.hpp"
#include "texture.hpp"
#include "vec.hpp"
#include "visit.hpp"
Expand All @@ -15,30 +15,29 @@ struct lambertian_material {
lambertian_material(const texture_t& a)
: albedo { a } {}

bool scatter(auto& ctx, const ray& r_in, const hit_record& rec,
color& attenuation, ray& scattered) const {
auto& rng = ctx.rng;
bool scatter(auto& ctx, const ray& r_in, const hit_record& rec, color& attenuation,
ray& scattered) const {
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };

vec scatter_direction = rec.normal + rng.unit_vec();
scattered = ray(rec.p, scatter_direction, r_in.time());
// Attenuation of the ray hitting the object is modified based on the color
// at hit point
attenuation *=
dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, albedo);
attenuation *= dev_visit([&](auto&& t) { return t.value(ctx, rec); }, albedo);
return true;
}
color emitted(auto&, const hit_record& rec) { return color(0, 0, 0); }
color emitted(auto&, const hit_record& rec) { return color(0.f, 0.f, 0.f); }
texture_t albedo;
};

struct metal_material {
metal_material() = default;
metal_material(const color& a, float f)
metal_material(const color& a, real_t f)
: albedo { a }
, fuzz { std::clamp(f, 0.0f, 1.0f) } {}

bool scatter(auto& ctx, const ray& r_in, const hit_record& rec,
color& attenuation, ray& scattered) const {
auto& rng = ctx.rng;
bool scatter(auto&, const ray& r_in, const hit_record& rec, color& attenuation,
ray& scattered) const {
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };

vec reflected = reflect(unit_vector(r_in.direction()), rec.normal);
scattered = ray(rec.p, reflected + fuzz * rng.in_unit_ball(), r_in.time());
// Attenuation of the ray hitting the object is modified based on the color
Expand All @@ -49,7 +48,7 @@ struct metal_material {

color emitted(auto&, const hit_record& rec) { return color(0, 0, 0); }
color albedo;
float fuzz;
real_t fuzz;
};

struct dielectric_material {
Expand All @@ -65,20 +64,19 @@ struct dielectric_material {
return r0 + (1 - r0) * sycl::pow((1 - cosine), 5.0f);
}

bool scatter(auto& ctx, const ray& r_in, const hit_record& rec,
color& attenuation, ray& scattered) const {
bool scatter(auto&, const ray& r_in, const hit_record& rec, color& attenuation,
ray& scattered) const {
// Attenuation of the ray hitting the object is modified based on the color
// at hit point
auto& rng = ctx.rng;
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };

attenuation *= albedo;
float refraction_ratio = rec.front_face ? (1.0f / ref_idx) : ref_idx;
real_t refraction_ratio = rec.front_face ? (1.0f / ref_idx) : ref_idx;
vec unit_direction = unit_vector(r_in.direction());
float cos_theta = sycl::fmin(-sycl::dot(unit_direction, rec.normal), 1.0f);
float sin_theta = sycl::sqrt(1.0f - cos_theta * cos_theta);
real_t cos_theta = sycl::fmin(-sycl::dot(unit_direction, rec.normal), 1.0f);
real_t sin_theta = sycl::sqrt(1.0f - cos_theta * cos_theta);
bool cannot_refract = refraction_ratio * sin_theta > 1.0f;
vec direction;
if (cannot_refract ||
reflectance(cos_theta, refraction_ratio) > rng.float_t())
if (cannot_refract || reflectance(cos_theta, refraction_ratio) > rng.real())
direction = reflect(unit_direction, rec.normal);
else
direction = refract(unit_direction, rec.normal, refraction_ratio);
Expand All @@ -104,7 +102,7 @@ struct lightsource_material {
template <typename... T> bool scatter(T&...) const { return false; }

color emitted(auto& ctx, const hit_record& rec) {
return dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, emit);
return dev_visit([&](auto&& t) { return t.value(ctx, rec); }, emit);
}

texture_t emit;
Expand All @@ -116,12 +114,11 @@ struct isotropic_material {
isotropic_material(texture_t& a)
: albedo { a } {}

bool scatter(auto& ctx, const ray& r_in, const hit_record& rec,
color& attenuation, ray& scattered) const {
auto& rng = ctx.rng;
bool scatter(auto& ctx, const ray& r_in, const hit_record& rec, color& attenuation,
ray& scattered) const {
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };
LocalPseudoRNG rng { toseed(r_in.direction(), r_in.origin()) };

I do not know why I am getting bored here...

scattered = ray(rec.p, rng.in_unit_ball(), r_in.time());
attenuation *=
dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, albedo);
attenuation *= dev_visit([&](auto&& t) { return t.value(ctx, rec); }, albedo);
return true;
}

Expand All @@ -133,5 +130,4 @@ struct isotropic_material {
using material_t =
std::variant<lambertian_material, metal_material, dielectric_material,
lightsource_material, isotropic_material>;

#endif
2 changes: 1 addition & 1 deletion include/ray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ray {

// returns point along the ray at distance t from ray's origin
// the ray P(t) = Origin + t*direction
point at(float t) const { return orig + t * dir; }
point at(real_t t) const { return orig + t * dir; }

public:
// To store the origin and direction of the ray
Expand Down
6 changes: 3 additions & 3 deletions include/rectangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class xy_rect {
, material_type { mat_type } {}

/// Compute ray interaction with rectangle
bool hit(auto&, const ray& r, real_t min, real_t max, hit_record& rec,
bool hit(const ray& r, real_t min, real_t max, hit_record& rec,
material_t& hit_material_type) const {
hit_material_type = material_type;

Expand Down Expand Up @@ -66,7 +66,7 @@ class xz_rect {
, material_type { mat_type } {}

/// Compute ray interaction with rectangle
bool hit(auto&, const ray& r, real_t min, real_t max, hit_record& rec,
bool hit(const ray& r, real_t min, real_t max, hit_record& rec,
material_t& hit_material_type) const {
hit_material_type = material_type;

Expand Down Expand Up @@ -104,7 +104,7 @@ class yz_rect {
, material_type { mat_type } {}

/// Compute ray interaction with rectangle
bool hit(auto&, const ray& r, real_t min, real_t max, hit_record& rec,
bool hit(const ray& r, real_t min, real_t max, hit_record& rec,
material_t& hit_material_type) const {
hit_material_type = material_type;

Expand Down
Loading