108 lines
2.8 KiB
C++
108 lines
2.8 KiB
C++
#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.point;
|
|
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.point;
|
|
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.point;
|
|
VectorNormalize(view);
|
|
|
|
|
|
// Vector from the light to the vertex
|
|
Vector direction = light.position - vert.point;
|
|
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;
|
|
}
|
|
|