ray-tracer-challenge/materials.h
2024-08-05 21:26:44 -05:00

69 lines
1.9 KiB
C

#pragma once
#include "tuples.h"
#include "lights.h"
#include "math.h"
struct material {
struct tuple color;
float ambient;
float diffuse;
float specular;
float shininess;
};
inline static struct material material()
{
return (struct material){
color(1.0f, 1.0f, 1.0f),
0.1f,
0.9f,
0.9f,
200.0f
};
}
inline static bool material_equal(struct material a, struct material b)
{
return
tuple_equal(a.color, b.color) &&
float_equal(a.ambient, b.ambient) &&
float_equal(a.diffuse, b.diffuse) &&
float_equal(a.specular, b.specular) &&
float_equal(a.shininess, b.shininess);
}
inline static struct tuple lighting(struct material material,
struct light light,
struct tuple point,
struct tuple eyev,
struct tuple normalv)
{
struct tuple effective_color = hadmard_product(material.color, light.intensity);
struct tuple lightv = tuple_normalize(tuple_sub(light.position, point));
struct tuple ambient = tuple_mul(effective_color, material.ambient);
float light_dot_normal = tuple_dot(lightv, normalv);
struct tuple diffuse;
struct tuple specular;
if (light_dot_normal < 0.0f) {
diffuse = color(0.0f, 0.0f, 0.0f); // black
specular = color(0.0f, 0.0f, 0.0f); // black
} else {
diffuse = tuple_mul(effective_color, material.diffuse * light_dot_normal);
struct tuple reflectv = tuple_reflect(tuple_neg(lightv), normalv);
float reflect_dot_eye = tuple_dot(reflectv, eyev);
if (reflect_dot_eye <= 0.0f) {
specular = color(0.0f, 0.0f, 0.0f); // black
} else {
float factor = powf(reflect_dot_eye, material.shininess);
specular = tuple_mul(light.intensity, material.specular * factor);
}
}
return tuple_add(tuple_add(ambient, diffuse), specular);
}