Add camera aperture / depth-of-field
This commit is contained in:
5
demo.c
5
demo.c
@@ -13,6 +13,8 @@
|
||||
#define MIN_RAD 1.0
|
||||
|
||||
#define FOV 90
|
||||
#define APERTURE 0.5
|
||||
#define FOCAL_LEN 100.0
|
||||
#define SAMPLES_PER_PIXEL 100
|
||||
|
||||
static const vec3_t camera_pos = { -100.0, 25.0, -100.0 };
|
||||
@@ -62,7 +64,8 @@ int main()
|
||||
rand_obj(objs + i, &rng);
|
||||
|
||||
img_t img = { .pix = pixbuf };
|
||||
camera_t camera = camera_init(camera_pos, target, FOV, W, H, APERTURE);
|
||||
camera_t camera
|
||||
= camera_init(camera_pos, target, FOV, W, H, APERTURE, FOCAL_LEN);
|
||||
|
||||
const scene_t scene = {
|
||||
.sky_colour = sky,
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
typedef struct {
|
||||
vec3_t pos;
|
||||
vec3_t pix_origin, x_step, y_step;
|
||||
vec3_t u_hat, v_hat;
|
||||
uint32_t img_width, img_height;
|
||||
double aperture;
|
||||
} camera_t;
|
||||
|
||||
camera_t camera_init(
|
||||
vec3_t pos, vec3_t target, double fov, uint32_t img_width,
|
||||
uint32_t img_height);
|
||||
uint32_t img_height, double aperture, double focal_len);
|
||||
|
||||
#endif
|
||||
|
||||
12
src/camera.c
12
src/camera.c
@@ -10,11 +10,8 @@ static const vec3_t up = { 0.0, 1.0, 0.0 };
|
||||
|
||||
camera_t camera_init(
|
||||
vec3_t pos, vec3_t target, double fov, uint32_t img_width,
|
||||
uint32_t img_height)
|
||||
uint32_t img_height, double aperture, double focal_len)
|
||||
{
|
||||
const vec3_t target_disp = vec3_sub(target, pos);
|
||||
const double focal_len = vec3_len(target_disp);
|
||||
|
||||
const double fov_rad = M_PI * fov / 180.0;
|
||||
const double aspect = (double)img_width / (double)img_height;
|
||||
const double viewport_height = focal_len * tan(fov_rad / 2);
|
||||
@@ -27,7 +24,9 @@ camera_t camera_init(
|
||||
const vec3_t u = vec3_scale(u_hat, viewport_width);
|
||||
const vec3_t v = vec3_scale(v_hat, -viewport_height);
|
||||
|
||||
const vec3_t topleft = vec3_sub(target, vec3_scale(vec3_add(u, v), 0.5));
|
||||
const vec3_t topleft = vec3_sub(
|
||||
vec3_add(pos, vec3_scale(w_hat, focal_len)),
|
||||
vec3_scale(vec3_add(u, v), 0.5));
|
||||
|
||||
const vec3_t x_step = vec3_scale(u, 1.0 / (double)img_width);
|
||||
const vec3_t y_step = vec3_scale(v, 1.0 / (double)img_height);
|
||||
@@ -39,7 +38,10 @@ camera_t camera_init(
|
||||
.pix_origin = pix_origin,
|
||||
.x_step = x_step,
|
||||
.y_step = y_step,
|
||||
.u_hat = u_hat,
|
||||
.v_hat = v_hat,
|
||||
.img_width = img_width,
|
||||
.img_height = img_height,
|
||||
.aperture = aperture,
|
||||
};
|
||||
}
|
||||
|
||||
14
src/render.c
14
src/render.c
@@ -94,9 +94,19 @@ static int render_thread(void *arg)
|
||||
vec3_scale(camera->y_step, jitter.y));
|
||||
const vec3_t jittered_pix = vec3_add(pix, offset);
|
||||
|
||||
vec3_t source = camera->pos;
|
||||
if (camera->aperture != 0.0) {
|
||||
const vec3_t pos
|
||||
= vec3_scale(rng_xy(&slice->rng), camera->aperture);
|
||||
const vec3_t offset = vec3_add(
|
||||
vec3_scale(camera->u_hat, pos.x),
|
||||
vec3_scale(camera->v_hat, pos.y));
|
||||
source = vec3_add(source, offset);
|
||||
}
|
||||
|
||||
const ray_t ray = {
|
||||
.orig = camera->pos,
|
||||
.dir = vec3_unit(vec3_sub(jittered_pix, camera->pos)),
|
||||
.orig = source,
|
||||
.dir = vec3_unit(vec3_sub(jittered_pix, source)),
|
||||
};
|
||||
const vec3_t sample = trace(ray, slice->scene, &slice->rng);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user