Make samples per pixel a camera parameter
This commit is contained in:
4
demo.c
4
demo.c
@@ -9,6 +9,7 @@
|
||||
#define H 600
|
||||
#define FOCAL_LEN 1.0
|
||||
#define VIEWPORT_H 2.0
|
||||
#define SAMPLES_PER_PIXEL 100
|
||||
|
||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
@@ -30,7 +31,8 @@ static pix_t pixbuf[W * H];
|
||||
int main()
|
||||
{
|
||||
img_t img = { .pix = pixbuf };
|
||||
camera_t camera = camera_init(camera_pos, FOCAL_LEN, VIEWPORT_H, W, H);
|
||||
camera_t camera = camera_init(
|
||||
camera_pos, FOCAL_LEN, VIEWPORT_H, W, H, SAMPLES_PER_PIXEL);
|
||||
camera_render(&camera, scene, NELEMS(scene), &img);
|
||||
|
||||
ff_write(STDOUT_FILENO, img);
|
||||
|
||||
@@ -11,11 +11,12 @@ typedef struct {
|
||||
vec3_t pos;
|
||||
vec3_t pix_origin, x_step, y_step;
|
||||
uint32_t img_width, img_height;
|
||||
unsigned samples_per_pixel;
|
||||
} camera_t;
|
||||
|
||||
camera_t camera_init(
|
||||
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
||||
uint32_t img_height);
|
||||
uint32_t img_height, unsigned samples_per_pixel);
|
||||
|
||||
void camera_render(
|
||||
const camera_t *camera, const obj_t *scene, unsigned scene_count,
|
||||
|
||||
15
src/camera.c
15
src/camera.c
@@ -11,14 +11,11 @@
|
||||
|
||||
#define MAX_ITER 10
|
||||
#define MIN_T 1e-6
|
||||
|
||||
#define NSAMPLES 100
|
||||
#define SAMPLE_WEIGHT (1.0 / (double)NSAMPLES)
|
||||
#define SAMPLE_STDDEV 0.333
|
||||
|
||||
#define GAMMA 2.2
|
||||
|
||||
#define NTHREADS 40
|
||||
#define NTHREADS 20
|
||||
|
||||
typedef struct {
|
||||
const camera_t *camera;
|
||||
@@ -54,7 +51,7 @@ trace(ray_t ray, const obj_t *scene, unsigned scene_count, rng_t *rng)
|
||||
|
||||
vec3_t atten;
|
||||
if (!material.scatter(material.params, hit, rng, &ray, &atten))
|
||||
break;
|
||||
return black;
|
||||
colour = vec3_hadamard(colour, atten);
|
||||
}
|
||||
|
||||
@@ -79,6 +76,7 @@ static int render_thread(void *arg)
|
||||
work_slice_t *slice = (work_slice_t *)arg;
|
||||
const camera_t *camera = slice->camera;
|
||||
const uint32_t w = camera->img_width;
|
||||
const double sample_weight = 1.0 / (double)camera->samples_per_pixel;
|
||||
|
||||
const unsigned stop_y = slice->start_y + slice->row_count;
|
||||
for (unsigned y = slice->start_y; y < stop_y; ++y) {
|
||||
@@ -88,7 +86,7 @@ static int render_thread(void *arg)
|
||||
const vec3_t pix = vec3_add(row, vec3_scale(camera->x_step, x));
|
||||
|
||||
vec3_t colour = black;
|
||||
for (unsigned i = 0; i < NSAMPLES; ++i) {
|
||||
for (unsigned i = 0; i < camera->samples_per_pixel; ++i) {
|
||||
const vec3_t jitter
|
||||
= rng_gaussian_xy(&slice->rng, SAMPLE_STDDEV);
|
||||
const vec3_t offset = vec3_add(
|
||||
@@ -102,7 +100,7 @@ static int render_thread(void *arg)
|
||||
const vec3_t sample = trace(
|
||||
ray, slice->scene, slice->scene_count, &slice->rng);
|
||||
|
||||
colour = vec3_add(colour, vec3_scale(sample, SAMPLE_WEIGHT));
|
||||
colour = vec3_add(colour, vec3_scale(sample, sample_weight));
|
||||
}
|
||||
|
||||
setpix(colour, slice->pixels + (w * y + x));
|
||||
@@ -116,7 +114,7 @@ static int render_thread(void *arg)
|
||||
|
||||
camera_t camera_init(
|
||||
vec3_t pos, double focal_len, double viewport_height, uint32_t img_width,
|
||||
uint32_t img_height)
|
||||
uint32_t img_height, unsigned samples_per_pixel)
|
||||
{
|
||||
const double aspect = (double)img_width / (double)img_height;
|
||||
const double viewport_width = viewport_height * aspect;
|
||||
@@ -138,6 +136,7 @@ camera_t camera_init(
|
||||
.y_step = y_step,
|
||||
.img_width = img_width,
|
||||
.img_height = img_height,
|
||||
.samples_per_pixel = samples_per_pixel,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user