Allow camera position and target position to vary
This commit is contained in:
24
demo.c
24
demo.c
@@ -7,22 +7,23 @@
|
|||||||
|
|
||||||
#define W 800
|
#define W 800
|
||||||
#define H 600
|
#define H 600
|
||||||
#define FOV 120
|
#define FOV 90
|
||||||
#define SAMPLES_PER_PIXEL 100
|
#define SAMPLES_PER_PIXEL 100
|
||||||
|
|
||||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
static const vec3_t camera_pos = { 0.0, 0.0, 0.0 };
|
static const vec3_t camera_pos = { 0.0, 1.5, -2.0 };
|
||||||
|
static const vec3_t camera_target = { 0.0, 1.0, 1.0 };
|
||||||
|
|
||||||
static const obj_t scene[] = {
|
static const obj_t scene[] = {
|
||||||
SPHERE(1.0, 0.0, -3.0, 1.0, LAMBERTIAN(0.6, 0.2, 0.8)),
|
SPHERE(1.0, 1.0, 3.0, 1.0, LAMBERTIAN(0.6, 0.2, 0.8)),
|
||||||
SPHERE(-0.8, 0.0, -3.8, 1.0, LAMBERTIAN(1.0, 1.0, 1.0)),
|
SPHERE(-0.8, 1.0, 3.8, 1.0, LAMBERTIAN(1.0, 1.0, 1.0)),
|
||||||
SPHERE(-1.0, -0.8, -2.6, 0.2, LAMBERTIAN(0.2, 0.9, 0.3)),
|
SPHERE(-1.0, 0.2, 2.6, 0.2, LAMBERTIAN(0.2, 0.9, 0.3)),
|
||||||
SPHERE(0.3, -0.7, -1.8, 0.3, LAMBERTIAN(0.9, 0.6, 0.2)),
|
SPHERE(0.3, 0.3, 1.8, 0.3, LAMBERTIAN(0.9, 0.6, 0.2)),
|
||||||
SPHERE(-1.6, -0.8, -2.0, 0.2, REFLECTIVE(1.0, 0.9, 0.4, 0.0)),
|
SPHERE(-1.6, 0.2, 2.0, 0.2, REFLECTIVE(1.0, 0.9, 0.4, 0.0)),
|
||||||
SPHERE(-6.0, 5.0, -5.0, 6.0, REFLECTIVE(0.9, 0.9, 0.9, 0.05)),
|
SPHERE(-6.0, 6.0, 5.0, 6.0, REFLECTIVE(0.9, 0.9, 0.9, 0.05)),
|
||||||
SPHERE(-0.7, -0.75, -1.5, 0.25, DIELECTRIC(1.5)),
|
SPHERE(-0.7, 0.25, 1.5, 0.25, DIELECTRIC(1.5)),
|
||||||
SPHERE(0.0, -1001.0, 0.0, 1000.0, LAMBERTIAN(0.3, 0.3, 0.3)),
|
SPHERE(0.0, -1000.0, 0.0, 1000.0, LAMBERTIAN(0.3, 0.3, 0.3)),
|
||||||
};
|
};
|
||||||
|
|
||||||
static pix_t pixbuf[W * H];
|
static pix_t pixbuf[W * H];
|
||||||
@@ -30,7 +31,8 @@ static pix_t pixbuf[W * H];
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
img_t img = { .pix = pixbuf };
|
img_t img = { .pix = pixbuf };
|
||||||
camera_t camera = camera_init(camera_pos, FOV, W, H, SAMPLES_PER_PIXEL);
|
camera_t camera = camera_init(
|
||||||
|
camera_pos, camera_target, FOV, W, H, SAMPLES_PER_PIXEL);
|
||||||
camera_render(&camera, scene, NELEMS(scene), &img);
|
camera_render(&camera, scene, NELEMS(scene), &img);
|
||||||
|
|
||||||
ff_write(STDOUT_FILENO, img);
|
ff_write(STDOUT_FILENO, img);
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ typedef struct {
|
|||||||
} camera_t;
|
} camera_t;
|
||||||
|
|
||||||
camera_t camera_init(
|
camera_t camera_init(
|
||||||
vec3_t pos, double fov, uint32_t img_width, uint32_t img_height,
|
vec3_t pos, vec3_t target, double fov, uint32_t img_width,
|
||||||
unsigned samples_per_pixel);
|
uint32_t img_height, unsigned samples_per_pixel);
|
||||||
|
|
||||||
void camera_render(
|
void camera_render(
|
||||||
const camera_t *camera, const obj_t *scene, unsigned scene_count,
|
const camera_t *camera, const obj_t *scene, unsigned scene_count,
|
||||||
|
|||||||
29
src/camera.c
29
src/camera.c
@@ -16,7 +16,6 @@
|
|||||||
#define MAX_ITER 10
|
#define MAX_ITER 10
|
||||||
#define MIN_T 1e-6
|
#define MIN_T 1e-6
|
||||||
#define SAMPLE_STDDEV 0.333
|
#define SAMPLE_STDDEV 0.333
|
||||||
#define FOCAL_LEN 1.0
|
|
||||||
|
|
||||||
#define GAMMA 2.2
|
#define GAMMA 2.2
|
||||||
|
|
||||||
@@ -31,6 +30,8 @@ typedef struct {
|
|||||||
atomic_uint *progress;
|
atomic_uint *progress;
|
||||||
} work_slice_t;
|
} work_slice_t;
|
||||||
|
|
||||||
|
static const vec3_t up = { 0.0, 1.0, 0.0 };
|
||||||
|
|
||||||
static const vec3_t lightblue = { 0.4, 0.6, 1.0 };
|
static const vec3_t lightblue = { 0.4, 0.6, 1.0 };
|
||||||
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
||||||
static const vec3_t black = { 0.0, 0.0, 0.0 };
|
static const vec3_t black = { 0.0, 0.0, 0.0 };
|
||||||
@@ -97,10 +98,11 @@ static int render_thread(void *arg)
|
|||||||
const vec3_t offset = vec3_add(
|
const vec3_t offset = vec3_add(
|
||||||
vec3_scale(camera->x_step, jitter.x),
|
vec3_scale(camera->x_step, jitter.x),
|
||||||
vec3_scale(camera->y_step, jitter.y));
|
vec3_scale(camera->y_step, jitter.y));
|
||||||
|
const vec3_t jittered_pix = vec3_add(pix, offset);
|
||||||
|
|
||||||
const ray_t ray = {
|
const ray_t ray = {
|
||||||
.orig = camera->pos,
|
.orig = camera->pos,
|
||||||
.dir = vec3_unit(vec3_add(pix, offset)),
|
.dir = vec3_unit(vec3_sub(jittered_pix, camera->pos)),
|
||||||
};
|
};
|
||||||
const vec3_t sample = trace(
|
const vec3_t sample = trace(
|
||||||
ray, slice->scene, slice->scene_count, &slice->rng);
|
ray, slice->scene, slice->scene_count, &slice->rng);
|
||||||
@@ -118,20 +120,23 @@ static int render_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
camera_t camera_init(
|
camera_t camera_init(
|
||||||
vec3_t pos, double fov, uint32_t img_width, uint32_t img_height,
|
vec3_t pos, vec3_t target, double fov, uint32_t img_width,
|
||||||
unsigned samples_per_pixel)
|
uint32_t img_height, unsigned samples_per_pixel)
|
||||||
{
|
{
|
||||||
const double aspect = (double)img_width / (double)img_height;
|
|
||||||
|
|
||||||
const double fov_rad = M_PI * fov / 180.0;
|
const double fov_rad = M_PI * fov / 180.0;
|
||||||
const double viewport_height = FOCAL_LEN * tan(fov_rad / 2);
|
const double aspect = (double)img_width / (double)img_height;
|
||||||
|
const double viewport_height = tan(fov_rad / 2);
|
||||||
const double viewport_width = viewport_height * aspect;
|
const double viewport_width = viewport_height * aspect;
|
||||||
const vec3_t viewport_disp = { 0, 0, FOCAL_LEN };
|
|
||||||
|
|
||||||
const vec3_t u = { viewport_width, 0, 0 };
|
const vec3_t w_hat = vec3_unit(vec3_sub(target, pos));
|
||||||
const vec3_t v = { 0, -viewport_height, 0 };
|
const vec3_t u_hat = vec3_unit(vec3_cross(up, w_hat));
|
||||||
const vec3_t topleft = vec3_sub(
|
const vec3_t v_hat = vec3_unit(vec3_cross(w_hat, u_hat));
|
||||||
vec3_sub(pos, viewport_disp), vec3_scale(vec3_add(u, v), 0.5));
|
|
||||||
|
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(vec3_add(pos, w_hat), vec3_scale(vec3_add(u, v), 0.5));
|
||||||
|
|
||||||
const vec3_t x_step = vec3_scale(u, 1.0 / (double)img_width);
|
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);
|
const vec3_t y_step = vec3_scale(v, 1.0 / (double)img_height);
|
||||||
|
|||||||
Reference in New Issue
Block a user