49 lines
1.6 KiB
C
49 lines
1.6 KiB
C
#pragma once
|
|
|
|
#include "materials.h"
|
|
#include "shapes.h"
|
|
#include "lights.h"
|
|
#include "patterns.h"
|
|
|
|
inline static struct tuple lighting(struct material material,
|
|
struct shape const * const object,
|
|
struct light light,
|
|
struct tuple point,
|
|
struct tuple eyev,
|
|
struct tuple normalv,
|
|
bool in_shadow)
|
|
{
|
|
struct tuple color;
|
|
if (material.has_pattern) {
|
|
color = pattern_at_object(material.pattern, object->transform, point);
|
|
} else {
|
|
color = material.color;
|
|
}
|
|
struct tuple effective_color = hadmard_product(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);
|
|
}
|
|
}
|
|
}
|