added Philox random gen

This commit is contained in:
Moritz Gmeiner 2023-12-29 10:59:06 +01:00
commit ec40eb11c1
6 changed files with 58 additions and 44 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "subprojects/philox"]
path = subprojects/philox
url = git@github.com:MorizzG/philox

View file

@ -3,7 +3,7 @@ project('ray-tracer', 'cpp', default_options : [
'werror=true', 'werror=true',
'cpp_std=c++23', 'cpp_std=c++23',
'b_lto=true', 'b_lto=true',
'b_lto_mode=thin', # 'b_lto_mode=thin',
]) ])
add_project_arguments( add_project_arguments(
@ -12,9 +12,14 @@ add_project_arguments(
language : 'cpp' language : 'cpp'
) )
philox_proj = subproject('philox', default_options : ['warning_level=0', 'werror=false'])
philox_dep = philox_proj.get_variable('philox_dep')
sources = [] sources = []
subdir('src') subdir('src')
inc = include_directories('src') inc = include_directories('src')
executable('ray-tracer', sources, include_directories : inc) executable('ray-tracer', sources, include_directories : inc, dependencies : [philox_dep])

View file

@ -15,18 +15,18 @@ int main(int /* argc */, char* /* argv */[]) {
RenderObjectList world; RenderObjectList world;
// world.Add(std::make_shared<Sphere>(Vec3{0, -100.5, -1}, 100)); world.Add(std::make_shared<Sphere>(Vec3{0, -100.5, -1}, 100));
world.Add(std::make_shared<Sphere>(-Vec3::e_z, 0.5)); world.Add(std::make_shared<Sphere>(-Vec3::e_z, 0.5));
// camera // camera
// constexpr f64 aspect_ratio = 16.0 / 9.0; constexpr f64 aspect_ratio = 16.0 / 9.0;
// constexpr u32 image_width = 800; constexpr u32 image_width = 800;
// constexpr auto image_height = static_cast<u32>(image_width / aspect_ratio); constexpr auto image_height = static_cast<u32>(image_width / aspect_ratio);
constexpr u32 image_width = 1920; // constexpr u32 image_width = 1920;
constexpr u32 image_height = 1080; // constexpr u32 image_height = 1080;
static_assert(image_height >= 1); static_assert(image_height >= 1);

View file

@ -1,47 +1,47 @@
#pragma once #pragma once
#include <cassert> #include <philox.h>
#include "raytracer.h" #include "raytracer.h"
class Random { #include "vec3.h"
class RandomGen {
public: public:
constexpr explicit Random(u64 j) { constexpr u64 GenU64() { return philox_.Next(); }
assert(j != v_); // constexpr u32 GenU32() { return static_cast<u32>(GenU64()); }
u_ = j ^ v_; constexpr f64 GenUniform() { return philox_.NextF64(); }
GenU64();
v_ = u_; constexpr f64 GenUniform(f64 min, f64 max) { return min + (max - min) * GenUniform(); }
GenU64();
w_ = v_; constexpr Vec3 GenVec3() { return Vec3{GenUniform(), GenUniform(), GenUniform()}; }
GenU64();
constexpr Vec3 GenVec3(f64 min, f64 max) {
return Vec3{GenUniform(min, max), GenUniform(min, max), GenUniform(min, max)};
} }
constexpr u64 GenU64() { constexpr Vec3 GenInUnitBall() {
u_ = u_ * 2862933555777941757ULL + 7046029254386353087ULL; while (true) {
Vec3 v = GenVec3(-1.0, 1.0);
v_ ^= v_ >> 17; if (v.norm() < 1.0) {
v_ ^= v_ << 31; return v;
v_ ^= v_ >> 8; }
}
w_ = 4294957665ULL * (w_ & 0xffffffffULL) + (w_ >> 32);
u64 x = u_ ^ (u_ << 21);
x ^= x >> 35;
x ^= x << 4;
return (x + v_) ^ w_;
} }
constexpr u32 GenU32() { return static_cast<u32>(GenU64()); } constexpr Vec3 GenOnUnitSphere() { return GenInUnitBall().normed(); }
constexpr f64 GenF64() { return 5.42101086242752217E-20 * static_cast<f64>(GenU64()); } constexpr Vec3 GenOnHemisphere(const Vec3& normal) {
Vec3 v = GenOnUnitSphere();
constexpr f64 GenF64(f64 min, f64 max) { return min + (max - min) * GenF64(); } if (dot(v, normal) < 0) {
v = -v;
}
return v;
}
private: private:
u64 u_ = 0ULL; Philox philox_;
u64 v_ = 4101842887655102017ULL;
u64 w_ = 1ULL;
}; };

View file

@ -15,7 +15,7 @@
class Renderer { class Renderer {
public: public:
constexpr explicit Renderer(Camera camera, u32 samples_per_pixel = 10) constexpr explicit Renderer(Camera camera, u32 samples_per_pixel = 10)
: camera_{camera}, rand_{0}, samples_per_pixel_{samples_per_pixel} {} : camera_{camera}, samples_per_pixel_{samples_per_pixel} {}
constexpr Image Render(const RenderObject& world) { constexpr Image Render(const RenderObject& world) {
Image img{camera_.image_width(), camera_.image_height()}; Image img{camera_.image_width(), camera_.image_height()};
@ -43,8 +43,8 @@ class Renderer {
constexpr Ray SampleRay(u32 i, u32 j) { constexpr Ray SampleRay(u32 i, u32 j) {
auto pixel_centre = camera_.PixelToWorld(i, j); auto pixel_centre = camera_.PixelToWorld(i, j);
Vec3 random_shift = rand_.GenF64(-0.5, 0.5) * camera_.d_u_pixel() + Vec3 random_shift = rand_.GenUniform(-0.5, 0.5) * camera_.d_u_pixel() +
rand_.GenF64(-0.5, 0.5) * camera_.d_v_pixel(); rand_.GenUniform(-0.5, 0.5) * camera_.d_v_pixel();
pixel_centre += random_shift; pixel_centre += random_shift;
@ -53,17 +53,22 @@ class Renderer {
return Ray{camera_.centre(), ray_direction}; return Ray{camera_.centre(), ray_direction};
} }
static constexpr Colour Cast(const Ray& ray, const RenderObject& world) { constexpr Colour Cast(const Ray& ray, const RenderObject& world) {
auto hit_record = world.hit(ray, Interval::kPositive); auto hit_record = world.hit(ray, Interval::kPositive);
if (hit_record.has_value()) { if (hit_record.has_value()) {
Vec3 n = hit_record->normal; Vec3 normal = hit_record->normal;
if (!hit_record->front_face) { if (!hit_record->front_face) {
return Colour::kBlack; return Colour::kBlack;
} }
return Colour{0.5 * (n + Vec3{1, 1, 1})}; Vec3 new_origin = hit_record->p;
Vec3 new_direction = rand_.GenOnHemisphere(normal);
Ray new_ray{new_origin, new_direction};
return 0.5 * Cast(new_ray, world);
} }
auto unit_dir = ray.direction().normed(); auto unit_dir = ray.direction().normed();
@ -75,7 +80,7 @@ class Renderer {
Camera camera_; Camera camera_;
Random rand_; RandomGen rand_{};
u32 samples_per_pixel_; u32 samples_per_pixel_;
}; };

1
subprojects/philox Submodule

@ -0,0 +1 @@
Subproject commit cf69284bd2d82b279c34fb1cf90543fd04b3a038