1
0
Fork 0
2018-soft-3d-renderer/src/light.cpp

108 lines
2.8 KiB
C++
Raw Normal View History

2018-09-20 02:15:53 +00:00
#include "camera.h"
2018-09-19 03:02:12 +00:00
#include "color.h"
#include "light.h"
// PRIVATE PROTOTYPES
static ColorF32 ComputeAmbientLight(
2018-09-20 02:15:53 +00:00
Material &material, ColorF32 &intensity);
2018-09-19 03:02:12 +00:00
static ColorF32 ComputeDiffuseLight(
2018-09-20 02:15:53 +00:00
Material &material, ColorF32 &intensity, Vertex &vert, Light &light);
static ColorF32 ComputeSpecularLight(
Material &material, ColorF32 &intensity, Vertex &vert, Light &light,
Camera &camera);
2018-09-19 03:02:12 +00:00
// PUBLIC FUNCTIONS
2018-09-20 02:15:53 +00:00
ColorF32 ComputeLight(
Vertex &vert, Material &material, Light &light, Camera &camera)
2018-09-19 03:02:12 +00:00
{
// Distance from light to vertex
2018-09-21 02:37:48 +00:00
Vector direction = light.position - vert.position;
2018-09-19 05:33:52 +00:00
float distance = VectorLength(direction);
2018-09-19 03:02:12 +00:00
2018-09-20 02:15:53 +00:00
// Point light intensity is a function of the falloff factors and the distance
2018-09-19 03:02:12 +00:00
ColorF32 intensity =
(light.intensity * light.color)
/ (light.falloffConstant + light.falloffLinear * distance);
// Compute ambient light
2018-09-20 02:15:53 +00:00
ColorF32 ambientLight = ComputeAmbientLight(material, intensity);
2018-09-19 03:02:12 +00:00
// Compute diffuse light
2018-09-20 02:15:53 +00:00
ColorF32 diffuseLight = ComputeDiffuseLight(material, intensity, vert, light);
// Compute specular light
ColorF32 specularLight = ComputeSpecularLight(material, intensity, vert, light, camera);
2018-09-19 03:02:12 +00:00
// Total light is sum of all lights
2018-09-20 02:15:53 +00:00
ColorF32 result = ambientLight + diffuseLight + specularLight;
2018-09-19 03:02:12 +00:00
return result;
}
// PRIVATE FUNCTIONS
static ColorF32 ComputeAmbientLight(
2018-09-20 02:15:53 +00:00
Material &material, ColorF32 &intensity)
2018-09-19 03:02:12 +00:00
{
2018-09-20 02:15:53 +00:00
// light = Kd * I
ColorF32 result = material.ambient * intensity;
2018-09-19 03:02:12 +00:00
2018-09-20 02:15:53 +00:00
return result;
}
static ColorF32 ComputeDiffuseLight(
Material &material, ColorF32 &intensity, Vertex &vert, Light &light)
{
// Vector from the light to the vertex
2018-09-21 02:37:48 +00:00
Vector direction = light.position - vert.position;
2018-09-20 02:15:53 +00:00
VectorNormalize(direction);
float normalDotDirection = VectorDot(vert.normal, direction);
// light = Kr * I * n.d
ColorF32 result = material.diffuse * intensity * normalDotDirection;
2018-09-19 03:02:12 +00:00
return result;
}
2018-09-20 02:15:53 +00:00
static ColorF32 ComputeSpecularLight(
Material &material, ColorF32 &intensity, Vertex &vert, Light &light,
Camera &camera)
2018-09-19 03:02:12 +00:00
{
2018-09-20 02:15:53 +00:00
// Vector from the camera to the vertex
2018-09-21 02:37:48 +00:00
Vector view = camera.position - vert.position;
2018-09-20 02:15:53 +00:00
VectorNormalize(view);
// Vector from the light to the vertex
2018-09-21 02:37:48 +00:00
Vector direction = light.position - vert.position;
2018-09-19 05:33:52 +00:00
VectorNormalize(direction);
2018-09-19 03:02:12 +00:00
2018-09-20 02:15:53 +00:00
// 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);
2018-09-19 03:02:12 +00:00
return result;
}