#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); }