diff --git a/color.hpp b/color.hpp index 98265fa..ca38d1f 100644 --- a/color.hpp +++ b/color.hpp @@ -12,9 +12,9 @@ void write_color(FILE *fp, color c, uint32_t samples_per_pixel) double scale = 1.0 / samples_per_pixel; // Divide the color by the number of samples - double r = c.x * scale; - double g = c.y * scale; - double b = c.z * scale; + double r = sqrt(c.x * scale); + double g = sqrt(c.y * scale); + double b = sqrt(c.z * scale); /* Write output */ fprintf(fp, diff --git a/main.cpp b/main.cpp index fe46796..26aafc2 100644 --- a/main.cpp +++ b/main.cpp @@ -8,15 +8,21 @@ #include "sphere.hpp" #include "camera.hpp" -color ray_color(const ray& r, const hittable& world); +color ray_color(const ray& r, const hittable& world, int32_t depth); double hit_sphere(const point3& center, double radius, const ray& r); -color ray_color(const ray& r, const hittable& world) +color ray_color(const ray& r, const hittable& world, int32_t depth) { + if (depth <= 0) + { + return color(0,0,0); + } + hit_record rec; if (world.hit(r, 0, INFINITY, rec)) { - return 0.5 * (rec.normal + color(1,1,1)); + point3 target = rec.p + rec.normal + random_in_unit_sphere(); + return 0.5 * ray_color(ray(rec.p, target - rec.p), world, depth-1); } vec3 unit_direction = normalize(r.direction); double t = 0.5 * (unit_direction.y + 1.0); @@ -47,6 +53,7 @@ int main() const int32_t image_width = 400; const int32_t image_height = (int32_t) (image_width / aspect_ratio); int32_t samples_per_pixel = 100; + int32_t max_depth = 50; if (getenv("SPP")) { @@ -79,7 +86,7 @@ int main() double u = ((i + random_double()) / (image_width-1)); double v = ((j + random_double()) / (image_height-1)); ray r = cam.get_ray(u,v); - pixel_color += ray_color(r, world); + pixel_color += ray_color(r, world, max_depth); } write_color(stdout, pixel_color, samples_per_pixel); diff --git a/rtweekend.hpp b/rtweekend.hpp index 9799046..dcb562a 100644 --- a/rtweekend.hpp +++ b/rtweekend.hpp @@ -13,7 +13,7 @@ double degrees_to_radians(double d) /* Returns a double in the range [0,1) */ inline double random_double() { - return rand() / RAND_MAX + 1.0; + return rand() * (1.0 / RAND_MAX); } /* Returns a double in the range [min,max) */ diff --git a/vec3.hpp b/vec3.hpp index fbb44f0..acc9513 100644 --- a/vec3.hpp +++ b/vec3.hpp @@ -1,8 +1,7 @@ #ifndef VEC3_H #define VEC3_H -#include -#include +#include "rtweekend.hpp" struct vec3 { /* Members */ @@ -65,6 +64,18 @@ struct vec3 { { return x*x + y*y + z*z; } + + // Get a vec3 with random components in the range [0,1) + inline static vec3 random() + { + return vec3(random_double(), random_double(), random_double()); + } + + // Get a vec3 with random components in the range [min, max) + inline static vec3 random(double min, double max) + { + return vec3(random_double(min, max), random_double(min, max), random_double(min, max)); + } }; /* Type aliases */ @@ -135,4 +146,17 @@ inline vec3 normalize(const vec3 v) return v / v.length(); } +// Returns a vec3 of random components between [-1,1) that is inside a unit sphere +vec3 random_in_unit_sphere() +{ + // Iterate until we find a vector with length < 1 + while (true) + { + vec3 p = vec3::random(-1,1); + if (p.length_squared() >= 1) + continue; + return p; + } +} + #endif