diff --git a/README.md b/README.md index b9324ca..977b66c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Raytracing in one weekend -[!img]() +![Movable lens](results/Camerazoom.png) diff --git a/results/Camerazoom.png b/results/Camerazoom.png new file mode 100644 index 0000000..d5b590f Binary files /dev/null and b/results/Camerazoom.png differ diff --git a/results/blur.png b/results/blur.png new file mode 100644 index 0000000..55e68e4 Binary files /dev/null and b/results/blur.png differ diff --git a/src/camera.h b/src/camera.h index 0593c28..17e2a60 100644 --- a/src/camera.h +++ b/src/camera.h @@ -8,7 +8,9 @@ class camera{ point3 lookat, vec3 vup, double vfov , - double aspect_ratio + double aspect_ratio, + double aperture, + double focus_dist ){ @@ -18,18 +20,21 @@ class camera{ auto viewport_height = 2.0 * h; auto viewport_width = aspect_ratio * viewport_height; - auto w = unit_vector(lookfrom - lookat); - auto u = unit_vector(cross(vup, w)); - auto v = cross(w,u); + w = unit_vector(lookfrom - lookat); + u = unit_vector(cross(vup, w)); + v = cross(w,u); origin = lookfrom; - horizontal = viewport_width * u; - vertical = viewport_height * v; - lower_left_corner = origin - horizontal/2 - vertical/2 - w; + horizontal = focus_dist * viewport_width * u; + vertical = focus_dist * viewport_height * v; + lower_left_corner = origin - horizontal/2 - vertical/2 - focus_dist * w; + lens_radius = aperture /2; } ray get_ray(double s, double t) const { - return ray(origin, lower_left_corner + s * horizontal + t*vertical - origin); + vec3 rd = lens_radius * random_in_unit_disk(); + vec3 offset = u * rd.x() + v * rd.y(); + return ray(origin + offset, lower_left_corner + s * horizontal + t * vertical - origin - offset); } private: @@ -37,4 +42,6 @@ class camera{ point3 lower_left_corner; vec3 horizontal; vec3 vertical; + vec3 u,v,w; + double lens_radius; }; diff --git a/src/program.cpp b/src/program.cpp index 8a76d43..1b3ceab 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -27,33 +27,76 @@ color ray_color(const ray& r, const hittable& world, int depth){ return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5,0.7,1.0); } +hittable_list random_scene(){ + hittable_list world; + + auto ground_material = make_shared(color(0.5,0.5,0.5)); + world.add(make_shared(point3(0,-1000,0), 1000, ground_material)); + + for(int a = -11; a < 11; a++){ + for(int b = -11; b < 11; b++){ + auto choose_mat = random_double(); + point3 center(a + 0.9 * random_double(), 0.2 , b+0.9* random_double()); + + if((center - point3(4,0.2,0)).length() > 0.9){ + shared_ptr sphere_material; + + if(choose_mat < 0.8){ + // diffuse + auto albedo = color::random() * color::random(); + sphere_material = make_shared(albedo); + world.add(make_shared(center, 0.2, sphere_material)); + } + else if(choose_mat < 0.95){ + // metal + auto albedo = color::random(0.5,1); + auto fuzz = random_double(0,0.5); + sphere_material = make_shared(albedo, fuzz ); + world.add(make_shared(center, 0.2, sphere_material)); + }else{ + // glass + sphere_material = make_shared(1.5); + world.add(make_shared(center, 0.2, sphere_material)); + } + } + } + } + +auto material1 = make_shared(1.5); +world.add(make_shared(point3(0,1,0), 1.0, material1)); + +auto material2 = make_shared(color(0.4, 0.2, 0.1)); +world.add(make_shared(point3(-4,1,0), 1.0, material2)); + +auto material3 = make_shared(color(0.7, 0.6, 0.5), 0.0); +world.add(make_shared(point3(4,1,0), 1.0, material3)); + +return world; + + +} + int main () { // Image - const auto aspect_ratio = 16.0 /9.0; - const int image_width = 400; + const auto aspect_ratio = 3.0 /2.0; + const int image_width = 1200; const int image_height = static_cast(image_width /aspect_ratio); - const int samples_per_pixel = 100; + const int samples_per_pixel = 500; const int max_depth = 50; // World - hittable_list world; - - auto material_ground = make_shared(color(0.8, 0.8, 0.0)); - auto material_center = make_shared(color(0.1, 0.2, 0.5)); - auto material_left = make_shared(1.5); - auto material_right = make_shared(color(0.8, 0.6, 0.2), 0.0); - - world.add(make_shared(point3( 0.0, -100.5, -1.0), 100.0, material_ground)); - world.add(make_shared(point3( 0.0, 0.0, -1.0), 0.5, material_center)); - world.add(make_shared(point3(-1.0, 0.0, -1.0), 0.5, material_left)); - world.add(make_shared(point3(-1.0, 0.0, -1.0), -0.45, material_left)); - world.add(make_shared(point3( 1.0, 0.0, -1.0), 0.5, material_right)); - + auto world = random_scene(); // Camera - camera cam(point3(-2,2,1), point3(0,0,-1), vec3(0,1,0), 20, aspect_ratio); + point3 lookfrom(13,2,3); + point3 lookat(0,0,0); + vec3 vup(0,1,0); + auto dist_to_focus = 10.0; + auto aperture = 0.1; + + camera cam(lookfrom, lookat , vup, 20, aspect_ratio, aperture, dist_to_focus); // Render std::cout<< "P3\n" << image_width << ' ' << image_height << "\n255\n"; diff --git a/src/vector3.h b/src/vector3.h index 1850bec..142097b 100644 --- a/src/vector3.h +++ b/src/vector3.h @@ -137,4 +137,12 @@ vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat){ vec3 r_out_perp = etai_over_etat * (uv + cos_theta*n); vec3 r_out_parallel = -sqrt(fabs(1.0 - r_out_perp.length_squared())) * n; return r_out_perp + r_out_parallel; +} + +vec3 random_in_unit_disk(){ + while(true){ + auto p = vec3(random_double(-1,1) , random_double(-1,1), 0); + if(p.length_squared() >= 1) continue; + return p; + } } \ No newline at end of file