From 92d66138f53645f3400f633c9821a6fa36f589e0 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Mon, 21 Dec 2020 01:26:14 +0100 Subject: Add lambertian reflection to spheres --- src/color.cpp | 14 ++++++++++---- src/main.cpp | 19 ++++++++++++++----- src/vec3.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/color.cpp b/src/color.cpp index 3cd3e60..565516f 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -2,10 +2,16 @@ #include "rt.hpp" void write_color(std::ostream& out, const color& pixel_color, uint32_t samples_per_pixel) { + auto r = pixel_color.x; + auto g = pixel_color.y; + auto b = pixel_color.z; + auto scale = 1.0 / samples_per_pixel; - auto scaled_color = pixel_color * scale; + r = sqrt(r * scale); + g = sqrt(g * scale); + b = sqrt(b * scale); - out << static_cast(256.0 * clamp(scaled_color.x, 0.0, 0.999)) << ' ' - << static_cast(256.0 * clamp(scaled_color.y, 0.0, 0.999)) << ' ' - << static_cast(256.0 * clamp(scaled_color.z, 0.0, 0.999)) << std::endl; + out << static_cast(256.0 * clamp(r, 0.0, 0.999)) << ' ' + << static_cast(256.0 * clamp(g, 0.0, 0.999)) << ' ' + << static_cast(256.0 * clamp(b, 0.0, 0.999)) << std::endl; } diff --git a/src/main.cpp b/src/main.cpp index f7c4b0e..62ef981 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,10 @@ color ground_color { 1.0, 1.0, 1.0 }; color sky_color { 0.5, 0.7, 1.0 }; -color ray_color(ray& r, const hittable& world) { +color ray_color(ray& r, const hittable& world, uint32_t depth) { + if (depth <= 0) { + return color{}; + } sphere sphere { { 0.0, 0.0, -1.0 }, 0.5 }; auto unit_dir = r.direction.unit(); @@ -15,8 +18,13 @@ color ray_color(ray& r, const hittable& world) { auto c = lerp(ground_color, sky_color, t); struct hit_info info; - if (world.hit(r, 0.0, infinity, info)) { - c = 0.5 * (info.normal + vec3{ 1.0, 1.0, 1.0}); + if (world.hit(r, 0.001, infinity, info)) { + // point3 target = info.point + info.normal + random_in_unit_sphere(); + // point3 target = info.point + info.normal + random_unit_vector(); + point3 target = info.point + info.normal + random_in_hemisphere(info.normal); + ray reflect { info.point, target - info.point }; + c = 0.5 * ray_color(reflect, world, depth - 1); + // c = 0.5 * (target - info.point + vec3{ 1.0, 1.0, 1.0 }); } return c; @@ -25,9 +33,10 @@ color ray_color(ray& r, const hittable& world) { int main() { // Image dimensions const double aspect_ratio = 16.0 / 9.0; - const size_t width = 400; + const size_t width = 1920; const size_t height = width / aspect_ratio; const uint32_t samples_per_pixel = 100; + const uint32_t max_depth = 100; camera camera { {}, aspect_ratio, 1.0 }; @@ -51,7 +60,7 @@ int main() { auto v = double(row + randd()) / (height - 1.0); auto ray = camera.get_ray(u, v); - pixel_color += ray_color(ray, world); + pixel_color += ray_color(ray, world, max_depth); } write_color(std::cout, pixel_color, samples_per_pixel); diff --git a/src/vec3.cpp b/src/vec3.cpp index f4470dc..f5b6909 100644 --- a/src/vec3.cpp +++ b/src/vec3.cpp @@ -1,4 +1,5 @@ #include "vec3.hpp" +#include "rt.hpp" vec3::vec3(): x(0.0), y(0.0), z(0.0) {} @@ -60,6 +61,14 @@ vec3 vec3::unit() const { return *this / length(); } +vec3 vec3::random() { + return vec3 { randd(), randd(), randd() }; +} + +vec3 vec3::random(double min, double max) { + return vec3 { randd(min, max), randd(min, max), randd(min, max) }; +} + vec3 lerp(vec3 u, vec3 v, double t) { return (1.0 - t) * u + t * v; } @@ -95,3 +104,24 @@ vec3 operator/(vec3 u, double scale) { std::ostream& operator<<(std::ostream& out, vec3 vec) { return out << vec.x << ' ' << vec.y << ' ' << vec.z << std::endl; } + +// TODO: Use something else to find random point onto a sphere +vec3 random_in_unit_sphere() { + while (true) { + auto p = vec3::random(-1,1); + if (p.length_sq() >= 1) continue; + return p; + } +} + +vec3 random_unit_vector() { + return random_in_unit_sphere().unit(); +} + +vec3 random_in_hemisphere(const vec3& normal) { + vec3 in_unit_sphere = random_in_unit_sphere(); + if (in_unit_sphere.dot(normal) > 0.0) // In the same hemisphere as the normal + return in_unit_sphere; + else + return -in_unit_sphere; +} -- cgit v1.3