Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize code for HLS #42

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
13 changes: 7 additions & 6 deletions include/box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ class box {
auto closest_so_far = max;
// Checking if the ray hits any of the sides
for (const auto& side : sides) {
if (dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, min, closest_so_far, temp_rec,
temp_material_type);
},
side)) {
if (dev_visit(monostate_dispatch(
[&](auto&& object) {
return object.hit(ctx, r, min, closest_so_far,
temp_rec, temp_material_type);
},
false),
side)) {
hit_anything = true;
closest_so_far = temp_rec.t;
rec = temp_rec;
Expand Down
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
30 changes: 16 additions & 14 deletions include/constant_medium.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "texture.hpp"
#include "visit.hpp"

using hittableVolume_t = std::variant<sphere, box>;
using hittableVolume_t = std::variant<std::monostate, sphere, box>;

/**
* A ray going through the volume can either make it all the way through
Expand All @@ -31,21 +31,23 @@ class constant_medium {
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,
lforg37 marked this conversation as resolved.
Show resolved Hide resolved
temp_material_type);
},
boundary)) {
if (!dev_visit(monostate_dispatch(
[&](auto&& object) {
return object.hit(ctx, r, -infinity, infinity, rec1,
temp_material_type);
},
false),
boundary)) {
return false;
}

if (!dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, rec1.t + 0.0001f, infinity, rec2,
temp_material_type);
},
boundary)) {
if (!dev_visit(monostate_dispatch(
[&](auto&& object) {
return object.hit(ctx, r, rec1.t + 0.0001f, infinity,
rec2, temp_material_type);
},
false),
boundary)) {
return false;
}

Expand All @@ -62,7 +64,7 @@ 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());
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?

27 changes: 7 additions & 20 deletions include/hitable.hpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
#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 "rectangle.hpp"
#include "sphere.hpp"
#include "triangle.hpp"

using hittable_t = std::variant<std::monostate, sphere, xy_rect, triangle, box,
constant_medium>;
#endif
39 changes: 22 additions & 17 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 @@ -22,17 +22,19 @@ struct lambertian_material {
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(
monostate_dispatch([&](auto&& t) { return t.value(ctx, rec); },
color { 0.f, 0.f, 0.f }),
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) } {}

Expand All @@ -47,9 +49,9 @@ struct metal_material {
return (dot(scattered.direction(), rec.normal) > 0);
}

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); }
color albedo;
float fuzz;
real_t fuzz;
};

struct dielectric_material {
Expand All @@ -71,14 +73,13 @@ struct dielectric_material {
// at hit point
auto& rng = ctx.rng;
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 +105,10 @@ 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(
monostate_dispatch([&](auto&& t) { return t.value(ctx, rec); },
color { 0.f, 0.f, 0.f }),
emit);
}

texture_t emit;
Expand All @@ -121,7 +125,9 @@ struct isotropic_material {
auto& rng = ctx.rng;
scattered = ray(rec.p, rng.in_unit_ball(), r_in.time());
attenuation *=
dev_visit([&](auto&& arg) { return arg.value(ctx, rec); }, albedo);
dev_visit(monostate_dispatch([&](auto&& t) { return t.value(ctx, rec); },
color { 0.f, 0.f, 0.f }),
albedo);
return true;
}

Expand All @@ -131,7 +137,6 @@ struct isotropic_material {
};

using material_t =
std::variant<lambertian_material, metal_material, dielectric_material,
lightsource_material, isotropic_material>;

std::variant<std::monostate, 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
45 changes: 21 additions & 24 deletions include/render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,17 @@
#include <variant>
#include <vector>

#include "box.hpp"
#include "build_parameters.hpp"
#include "camera.hpp"
#include "constant_medium.hpp"
#include "hitable.hpp"
#include "material.hpp"
#include "ray.hpp"
#include "rectangle.hpp"
#include "rtweekend.hpp"
#include "sphere.hpp"
#include "sycl.hpp"
#include "texture.hpp"
#include "triangle.hpp"
#include "vec.hpp"
#include "visit.hpp"

using hittable_t =
std::variant<sphere, xy_rect, triangle, box, constant_medium>;

template <int width, int height, int samples, int depth>
inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
auto& hittable_acc, auto fb_acc) {
Expand All @@ -35,12 +27,13 @@ inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
auto closest_so_far = infinity;
// Checking if the ray hits any of the spheres
for (auto i = 0; i < hittable_acc.get_count(); i++) {
if (dev_visit(
[&](auto&& arg) {
return arg.hit(ctx, r, 0.001f, closest_so_far, temp_rec,
temp_material_type);
},
hittable_acc[i])) {
if (dev_visit(monostate_dispatch(
[&](auto&& object) {
return object.hit(ctx, r, 0.001f, closest_so_far,
temp_rec, temp_material_type);
},
false),
hittable_acc[i])) {
hit_anything = true;
closest_so_far = temp_rec.t;
rec = temp_rec;
Expand All @@ -58,14 +51,18 @@ inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,
for (auto i = 0; i < depth; i++) {
hit_record rec;
if (hit_world(cur_ray, rec, material_type)) {
emitted = dev_visit([&](auto&& arg) { return arg.emitted(ctx, rec); },
material_type);
if (dev_visit(
[&](auto&& arg) {
return arg.scatter(ctx, cur_ray, rec, cur_attenuation,
scattered);
},
material_type)) {
emitted =
dev_visit(monostate_dispatch(
[&](auto&& mat) { return mat.emitted(ctx, rec); },
color { 0.f, 0.f, 0.f }),
material_type);
if (dev_visit(monostate_dispatch(
[&](auto&& mat) {
return mat.scatter(ctx, cur_ray, rec,
cur_attenuation, scattered);
},
false),
material_type)) {
// On hitting the object, the ray gets scattered
cur_ray = scattered;
} else {
Expand Down Expand Up @@ -93,8 +90,8 @@ inline auto render_pixel(auto& ctx, int x_coord, int y_coord, camera const& cam,

color final_color(0.0f, 0.0f, 0.0f);
for (auto i = 0; i < samples; i++) {
const auto u = (x_coord + rng.float_t()) / width;
const auto v = (y_coord + rng.float_t()) / height;
const auto u = (x_coord + rng.real()) / width;
const auto v = (y_coord + rng.real()) / height;
// u and v are points on the viewport
ray r = cam.get_ray(u, v, rng);
final_color += get_color(r);
Expand Down
Loading