Add defocus blur
This commit is contained in:
parent
e5e5863c1d
commit
482a3bf196
25
camera.c
25
camera.c
@ -6,29 +6,38 @@
|
||||
#include <math.h>
|
||||
|
||||
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 h = tan(theta / 2.0);
|
||||
double viewport_height = 2.0 * h;
|
||||
double viewport_width = aspect_ratio * viewport_height;
|
||||
|
||||
Vec3 w = vec3_normalize(point3_sub(look_from, look_at));
|
||||
Vec3 u = vec3_normalize(vec3_cross(up, w));
|
||||
Vec3 v = vec3_cross(w, u);
|
||||
camera->w = vec3_normalize(point3_sub(look_from, look_at));
|
||||
camera->u = vec3_normalize(vec3_cross(up, camera->w));
|
||||
camera->v = vec3_cross(camera->w, camera->u);
|
||||
|
||||
camera->origin = look_from;
|
||||
camera->horizontal = vec3_mul(viewport_width, u);
|
||||
camera->vertical = vec3_mul(viewport_height, v);
|
||||
camera->horizontal = vec3_mul(focus_distance * viewport_width, camera->u);
|
||||
camera->vertical = vec3_mul(focus_distance * viewport_height, camera->v);
|
||||
Vec3 offset =
|
||||
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->lens_radius = aperture / 2.0;
|
||||
}
|
||||
|
||||
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(
|
||||
camera->lower_left_corner,
|
||||
vec3_add(vec3_mul(s, camera->horizontal), vec3_mul(t, camera->vertical)));
|
||||
Vec3 direction = point3_sub(screen_point, camera->origin);
|
||||
return (Ray){camera->origin, direction};
|
||||
return (Ray){
|
||||
point3_add(camera->origin, offset),
|
||||
vec3_sub(direction, offset),
|
||||
};
|
||||
}
|
||||
|
||||
5
camera.h
5
camera.h
@ -10,10 +10,13 @@ typedef struct Camera {
|
||||
Point3 lower_left_corner;
|
||||
Vec3 horizontal;
|
||||
Vec3 vertical;
|
||||
Vec3 u, v, w;
|
||||
double lens_radius;
|
||||
} Camera;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
11
main.c
11
main.c
@ -90,9 +90,16 @@ int main(void) {
|
||||
hittable_list_add(&world, (const Hittable *)&sphere_right);
|
||||
|
||||
/* 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_init(&camera, (Point3){-2.0, 2.0, 1.0}, (Point3){0.0, 0.0, -1.0},
|
||||
(Vec3){0.0, 1.0, 0.0}, 20, aspect_ratio);
|
||||
camera_init(&camera, look_from, look_at, up, 20, aspect_ratio, aperture,
|
||||
dist_to_focus);
|
||||
|
||||
printf("P3\n%u %u\n255\n", image_width, image_height);
|
||||
|
||||
|
||||
16
vec3.c
16
vec3.c
@ -52,9 +52,19 @@ Vec3 vec3_random_in_range(double min, double max) {
|
||||
}
|
||||
|
||||
Vec3 vec3_random_in_unit_sphere(void) {
|
||||
while (1) {
|
||||
Vec3 result = vec3_random_in_range(-1, 1);
|
||||
if (vec3_length2(result) >= 1)
|
||||
while (true) {
|
||||
Vec3 result = vec3_random_in_range(-1.0, 1.0);
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user