Add fuzz parameter to reflective material

This commit is contained in:
2025-09-23 15:36:08 +01:00
parent 1e31fae5d0
commit 90240ee5ad
3 changed files with 12 additions and 6 deletions

4
demo.c
View File

@@ -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(-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(-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(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(-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)), 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.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)), SPHERE(0.0, -1001.0, 0.0, 1000.0, LAMBERTIAN(0.3, 0.3, 0.3)),
}; };

View File

@@ -10,10 +10,10 @@
.params = { .lambertian = { .albedo = { r, g, b } } }, \ .params = { .lambertian = { .albedo = { r, g, b } } }, \
} }
#define REFLECTIVE(r, g, b) \ #define REFLECTIVE(r, g, b, f) \
{ \ { \
.scatter = scatter_reflective, \ .scatter = scatter_reflective, \
.params = { .reflective = { .tint = { r, g, b } } }, \ .params = { .reflective = { .tint = { r, g, b }, .fuzz = f } }, \
} }
#define DIELECTRIC(e) \ #define DIELECTRIC(e) \
@@ -34,6 +34,7 @@ typedef struct {
typedef struct { typedef struct {
vec3_t tint; vec3_t tint;
double fuzz;
} reflective_params_t; } reflective_params_t;
typedef struct { typedef struct {

View File

@@ -34,10 +34,15 @@ bool scatter_reflective(
material_params_t params, hit_t hit, rng_t *rng, ray_t *ray, material_params_t params, hit_t hit, rng_t *rng, ray_t *ray,
vec3_t *atten_out) 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->orig = hit.point;
ray->dir = reflect(ray->dir, hit.normal); ray->dir = reflected;
*atten_out = params.reflective.tint; *atten_out = params.reflective.tint;
return true; return true;
} }