Add defocus blur

This commit is contained in:
Jean-Michel Gorius 2022-11-11 22:58:22 +01:00
parent e5e5863c1d
commit 482a3bf196
5 changed files with 44 additions and 14 deletions

View File

@ -6,29 +6,38 @@
#include <math.h> #include <math.h>
void camera_init(Camera *camera, Point3 look_from, Point3 look_at, Vec3 up, void camera_init(Camera *camera, Point3 look_from, Point3 look_at, Vec3 up,
double vertical_fov, double aspect_ratio) { double vertical_fov, double aspect_ratio, double aperture,
double focus_distance) {
double theta = degrees_to_radians(vertical_fov); double theta = degrees_to_radians(vertical_fov);
double h = tan(theta / 2.0); double h = tan(theta / 2.0);
double viewport_height = 2.0 * h; double viewport_height = 2.0 * h;
double viewport_width = aspect_ratio * viewport_height; double viewport_width = aspect_ratio * viewport_height;
Vec3 w = vec3_normalize(point3_sub(look_from, look_at)); camera->w = vec3_normalize(point3_sub(look_from, look_at));
Vec3 u = vec3_normalize(vec3_cross(up, w)); camera->u = vec3_normalize(vec3_cross(up, camera->w));
Vec3 v = vec3_cross(w, u); camera->v = vec3_cross(camera->w, camera->u);
camera->origin = look_from; camera->origin = look_from;
camera->horizontal = vec3_mul(viewport_width, u); camera->horizontal = vec3_mul(focus_distance * viewport_width, camera->u);
camera->vertical = vec3_mul(viewport_height, v); camera->vertical = vec3_mul(focus_distance * viewport_height, camera->v);
Vec3 offset = Vec3 offset =
vec3_add(vec3_div(camera->horizontal, 2), vec3_div(camera->vertical, 2)); vec3_add(vec3_div(camera->horizontal, 2), vec3_div(camera->vertical, 2));
offset = vec3_add(offset, w); offset = vec3_add(offset, vec3_mul(focus_distance, camera->w));
camera->lower_left_corner = point3_add(camera->origin, vec3_neg(offset)); camera->lower_left_corner = point3_add(camera->origin, vec3_neg(offset));
camera->lens_radius = aperture / 2.0;
} }
Ray camera_get_ray(const Camera *camera, double s, double t) { Ray camera_get_ray(const Camera *camera, double s, double t) {
Vec3 rd = vec3_mul(camera->lens_radius, vec3_random_in_unit_disk());
Vec3 offset = vec3_add(vec3_mul(rd.x, camera->u), vec3_mul(rd.y, camera->v));
Point3 screen_point = point3_add( Point3 screen_point = point3_add(
camera->lower_left_corner, camera->lower_left_corner,
vec3_add(vec3_mul(s, camera->horizontal), vec3_mul(t, camera->vertical))); vec3_add(vec3_mul(s, camera->horizontal), vec3_mul(t, camera->vertical)));
Vec3 direction = point3_sub(screen_point, camera->origin); Vec3 direction = point3_sub(screen_point, camera->origin);
return (Ray){camera->origin, direction}; return (Ray){
point3_add(camera->origin, offset),
vec3_sub(direction, offset),
};
} }

View File

@ -10,10 +10,13 @@ typedef struct Camera {
Point3 lower_left_corner; Point3 lower_left_corner;
Vec3 horizontal; Vec3 horizontal;
Vec3 vertical; Vec3 vertical;
Vec3 u, v, w;
double lens_radius;
} Camera; } Camera;
void camera_init(Camera *camera, Point3 look_from, Point3 look_at, Vec3 up, void camera_init(Camera *camera, Point3 look_from, Point3 look_at, Vec3 up,
double vertical_fov, double aspect_ratio); double vertical_fov, double aspect_ratio, double aperture,
double focus_distance);
Ray camera_get_ray(const Camera *camera, double s, double t); Ray camera_get_ray(const Camera *camera, double s, double t);

11
main.c
View File

@ -90,9 +90,16 @@ int main(void) {
hittable_list_add(&world, (const Hittable *)&sphere_right); hittable_list_add(&world, (const Hittable *)&sphere_right);
/* Camera */ /* Camera */
Point3 look_from = {3.0, 3.0, 2.0};
Point3 look_at = {0.0, 0.0, -1.0};
Vec3 up = {0.0, 1.0, 0.0};
double dist_to_focus = vec3_length(point3_sub(look_from, look_at));
double aperture = 2.0;
Camera camera; Camera camera;
camera_init(&camera, (Point3){-2.0, 2.0, 1.0}, (Point3){0.0, 0.0, -1.0}, camera_init(&camera, look_from, look_at, up, 20, aspect_ratio, aperture,
(Vec3){0.0, 1.0, 0.0}, 20, aspect_ratio); dist_to_focus);
printf("P3\n%u %u\n255\n", image_width, image_height); printf("P3\n%u %u\n255\n", image_width, image_height);

16
vec3.c
View File

@ -52,9 +52,19 @@ Vec3 vec3_random_in_range(double min, double max) {
} }
Vec3 vec3_random_in_unit_sphere(void) { Vec3 vec3_random_in_unit_sphere(void) {
while (1) { while (true) {
Vec3 result = vec3_random_in_range(-1, 1); Vec3 result = vec3_random_in_range(-1.0, 1.0);
if (vec3_length2(result) >= 1) if (vec3_length2(result) >= 1.0)
continue;
return result;
}
}
Vec3 vec3_random_in_unit_disk(void) {
while (true) {
Vec3 result = (Vec3){random_double_in_range(-1.0, 1.0),
random_double_in_range(-1.0, 1.0), 0.0};
if (vec3_length2(result) >= 1.0)
continue; continue;
return result; return result;
} }

1
vec3.h
View File

@ -24,6 +24,7 @@ Vec3 vec3_cross(Vec3 v1, Vec3 v2);
Vec3 vec3_random(void); Vec3 vec3_random(void);
Vec3 vec3_random_in_range(double min, double max); Vec3 vec3_random_in_range(double min, double max);
Vec3 vec3_random_in_unit_sphere(void); Vec3 vec3_random_in_unit_sphere(void);
Vec3 vec3_random_in_unit_disk(void);
Vec3 vec3_random_unit_vector(void); Vec3 vec3_random_unit_vector(void);
bool vec3_is_near_zero(Vec3 v); bool vec3_is_near_zero(Vec3 v);