#include "camera.h" #include "color.h" #include "light.h" // PRIVATE PROTOTYPES static ColorF32 ComputeAmbientLight( Material &material, ColorF32 &intensity); static ColorF32 ComputeDiffuseLight( Material &material, ColorF32 &intensity, Vertex &vert, Light &light); static ColorF32 ComputeSpecularLight( Material &material, ColorF32 &intensity, Vertex &vert, Light &light, Camera &camera); // PUBLIC FUNCTIONS ColorF32 ComputeLight( Vertex &vert, Material &material, Light &light, Camera &camera) { // Distance from light to vertex Vector direction = light.position - vert.position; float distance = VectorLength(direction); // Point light intensity is a function of the falloff factors and the distance ColorF32 intensity = (light.intensity * light.color) / (light.falloffConstant + light.falloffLinear * distance); // Compute ambient light ColorF32 ambientLight = ComputeAmbientLight(material, intensity); // Compute diffuse light ColorF32 diffuseLight = ComputeDiffuseLight(material, intensity, vert, light); // Compute specular light ColorF32 specularLight = ComputeSpecularLight(material, intensity, vert, light, camera); // Total light is sum of all lights ColorF32 result = ambientLight + diffuseLight + specularLight; return result; } // PRIVATE FUNCTIONS static ColorF32 ComputeAmbientLight( Material &material, ColorF32 &intensity) { // light = Kd * I ColorF32 result = material.ambient * intensity; return result; } static ColorF32 ComputeDiffuseLight( Material &material, ColorF32 &intensity, Vertex &vert, Light &light) { // Vector from the light to the vertex Vector direction = light.position - vert.position; VectorNormalize(direction); float normalDotDirection = VectorDot(vert.normal, direction); // light = Kr * I * n.d ColorF32 result = material.diffuse * intensity * normalDotDirection; return result; } static ColorF32 ComputeSpecularLight( Material &material, ColorF32 &intensity, Vertex &vert, Light &light, Camera &camera) { // Vector from the camera to the vertex Vector view = camera.position - vert.position; VectorNormalize(view); // Vector from the light to the vertex Vector direction = light.position - vert.position; VectorNormalize(direction); // Reflection vector of the light vector across the vertex normal float normalDotDirection = VectorDot(vert.normal, direction); Vector reflection = (2.0f * normalDotDirection * vert.normal) - direction; float reflectDotView = MAX(VectorDot(reflection, view), 0.0f); // light = Ks * I * (r.v)^sp ColorF32 result = material.specular * intensity * powf(reflectDotView, material.specularExp); return result; }