Implement diffuse scattering

This commit is contained in:
2025-09-23 15:36:08 +01:00
parent 83154d7548
commit c92f43ca3c

View File

@@ -1,23 +1,46 @@
#include "camera.h" #include "camera.h"
#include "ray.h" #include "ray.h"
#include "rng.h"
#include <float.h> #include <float.h>
#include <stdio.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 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 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) static vec3_t trace(ray_t ray, const obj_t *scene, unsigned scene_count)
{ {
hit_t hit = { .t = DBL_MAX }; double coeff = 1.0;
for (unsigned i = 0; i < scene_count; ++i) for (unsigned i = 0; i < MAX_ITER; ++i) {
scene[i].intersect(scene[i].params, ray, &hit, 0.0, hit.t); hit_t hit = { .t = DBL_MAX };
if (hit.t != DBL_MAX) for (unsigned j = 0; j < scene_count; ++j)
return vec3_scale(vec3_add(hit.normal, white), 0.5); scene[j].intersect(scene[j].params, ray, &hit, MIN_T, hit.t);
const double a = (ray.dir.y + 1.0) / 2.0; if (hit.t == DBL_MAX) {
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a)); 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) static void setpix(vec3_t col, pix_t *out)