70 lines
1.9 KiB
C
70 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,
|
|
bool in_shadow)
|
|
{
|
|
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);
|
|
|
|
if (in_shadow) {
|
|
return ambient;
|
|
}
|
|
|
|
float light_dot_normal = tuple_dot(lightv, normalv);
|
|
if (light_dot_normal < 0.0f) {
|
|
return ambient;
|
|
} else {
|
|
struct tuple 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) {
|
|
return tuple_add(ambient, diffuse);
|
|
} else {
|
|
float factor = powf(reflect_dot_eye, material.shininess);
|
|
struct tuple specular = tuple_mul(light.intensity, material.specular * factor);
|
|
return tuple_add(tuple_add(ambient, diffuse), specular);
|
|
}
|
|
}
|
|
}
|