Implement diffuse scattering
This commit is contained in:
37
src/camera.c
37
src/camera.c
@@ -1,23 +1,46 @@
|
||||
#include "camera.h"
|
||||
|
||||
#include "ray.h"
|
||||
#include "rng.h"
|
||||
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_ITER 10
|
||||
#define MIN_T 1e-6
|
||||
|
||||
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 black = { 0.0, 0.0, 0.0 };
|
||||
|
||||
static ray_t scatter(hit_t hit)
|
||||
{
|
||||
const vec3_t rand = rng_vec3();
|
||||
const vec3_t dir
|
||||
= vec3_dot(rand, hit.normal) > 0.0 ? rand : vec3_scale(rand, -1.0);
|
||||
return (ray_t) { .orig = hit.point, .dir = dir };
|
||||
}
|
||||
|
||||
static vec3_t trace(ray_t ray, const obj_t *scene, unsigned scene_count)
|
||||
{
|
||||
hit_t hit = { .t = DBL_MAX };
|
||||
for (unsigned i = 0; i < scene_count; ++i)
|
||||
scene[i].intersect(scene[i].params, ray, &hit, 0.0, hit.t);
|
||||
if (hit.t != DBL_MAX)
|
||||
return vec3_scale(vec3_add(hit.normal, white), 0.5);
|
||||
double coeff = 1.0;
|
||||
for (unsigned i = 0; i < MAX_ITER; ++i) {
|
||||
hit_t hit = { .t = DBL_MAX };
|
||||
for (unsigned j = 0; j < scene_count; ++j)
|
||||
scene[j].intersect(scene[j].params, ray, &hit, MIN_T, hit.t);
|
||||
|
||||
const double a = (ray.dir.y + 1.0) / 2.0;
|
||||
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a));
|
||||
if (hit.t == DBL_MAX) {
|
||||
const double a = (ray.dir.y + 1.0) / 2.0;
|
||||
return vec3_scale(
|
||||
vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a)),
|
||||
coeff);
|
||||
}
|
||||
|
||||
ray = scatter(hit);
|
||||
coeff *= 0.5;
|
||||
}
|
||||
|
||||
return black;
|
||||
}
|
||||
|
||||
static void setpix(vec3_t col, pix_t *out)
|
||||
|
||||
Reference in New Issue
Block a user