Defocus blur + Final render

The last of the RaytracingInOneWeekend post.
Very cool thing to go through.
master
Nigel Barink 2023-03-05 17:01:15 +01:00
parent 3d06a33548
commit d3a12c9bbb
6 changed files with 84 additions and 26 deletions

View File

@ -1,7 +1,7 @@
# Raytracing in one weekend
[!img]()
![Movable lens](results/Camerazoom.png)

BIN
results/Camerazoom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
results/blur.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -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;
};

View File

@ -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<lambertian>(color(0.5,0.5,0.5));
world.add(make_shared<sphere>(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<material> sphere_material;
if(choose_mat < 0.8){
// diffuse
auto albedo = color::random() * color::random();
sphere_material = make_shared<lambertian>(albedo);
world.add(make_shared<sphere>(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<metal>(albedo, fuzz );
world.add(make_shared<sphere>(center, 0.2, sphere_material));
}else{
// glass
sphere_material = make_shared<dielectric>(1.5);
world.add(make_shared<sphere>(center, 0.2, sphere_material));
}
}
}
}
auto material1 = make_shared<dielectric>(1.5);
world.add(make_shared<sphere>(point3(0,1,0), 1.0, material1));
auto material2 = make_shared<lambertian>(color(0.4, 0.2, 0.1));
world.add(make_shared<sphere>(point3(-4,1,0), 1.0, material2));
auto material3 = make_shared<metal>(color(0.7, 0.6, 0.5), 0.0);
world.add(make_shared<sphere>(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<int>(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<lambertian>(color(0.8, 0.8, 0.0));
auto material_center = make_shared<lambertian>(color(0.1, 0.2, 0.5));
auto material_left = make_shared<dielectric>(1.5);
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
world.add(make_shared<sphere>(point3( 0.0, -100.5, -1.0), 100.0, material_ground));
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.0), 0.5, material_center));
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), -0.45, material_left));
world.add(make_shared<sphere>(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";

View File

@ -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;
}
}