From 157bf8d93e4b0469d43fbeb6e3c7d3c4e5f34391 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Mon, 22 Sep 2025 16:13:55 +0100 Subject: [PATCH] Add fuzz parameter to reflective material --- demo.c | 4 ++-- include/material.h | 5 +++-- src/material.c | 9 +++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/demo.c b/demo.c index 2d3e103..262efff 100644 --- a/demo.c +++ b/demo.c @@ -20,8 +20,8 @@ static const obj_t scene[] = { SPHERE(-0.8, 0.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(0.3, -0.7, -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)), - SPHERE(-6.0, 5.0, -5.0, 6.0, REFLECTIVE(0.9, 0.9, 0.9)), + SPHERE(-1.6, -0.8, -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(-0.7, -0.75, -1.5, 0.25, DIELECTRIC(1.5)), SPHERE(0.0, -1001.0, 0.0, 1000.0, LAMBERTIAN(0.3, 0.3, 0.3)), }; diff --git a/include/material.h b/include/material.h index 6c49cc4..ec2bb41 100644 --- a/include/material.h +++ b/include/material.h @@ -10,10 +10,10 @@ .params = { .lambertian = { .albedo = { r, g, b } } }, \ } -#define REFLECTIVE(r, g, b) \ +#define REFLECTIVE(r, g, b, f) \ { \ .scatter = scatter_reflective, \ - .params = { .reflective = { .tint = { r, g, b } } }, \ + .params = { .reflective = { .tint = { r, g, b }, .fuzz = f } }, \ } #define DIELECTRIC(e) \ @@ -34,6 +34,7 @@ typedef struct { typedef struct { vec3_t tint; + double fuzz; } reflective_params_t; typedef struct { diff --git a/src/material.c b/src/material.c index 87321fe..bed8db1 100644 --- a/src/material.c +++ b/src/material.c @@ -34,10 +34,15 @@ bool scatter_reflective( material_params_t params, hit_t hit, rng_t *rng, ray_t *ray, vec3_t *atten_out) { - (void)rng; + vec3_t reflected = reflect(ray->dir, hit.normal); + if (params.reflective.fuzz != 0.0) { + const double weight = params.reflective.fuzz * rng_canon(rng); + const vec3_t scatter = vec3_scale(rng_vec3(rng), weight); + reflected = vec3_unit(vec3_add(reflected, scatter)); + } ray->orig = hit.point; - ray->dir = reflect(ray->dir, hit.normal); + ray->dir = reflected; *atten_out = params.reflective.tint; return true; }