1
0
Fork 0

Add specular lighting

This commit is contained in:
Austin Morlan 2018-09-19 19:15:53 -07:00
parent e87546c8b1
commit abf9e8fa7c
Signed by: austin
GPG Key ID: FD6B27654AF5E348
4 changed files with 78 additions and 35 deletions

View File

@ -1,6 +1,7 @@
#ifndef LIGHT_H #ifndef LIGHT_H
#include "camera.h"
#include "color.h" #include "color.h"
#include "geometry.h" #include "geometry.h"
#include "point.h" #include "point.h"
@ -18,7 +19,7 @@ struct Light
// PUBLIC FUNCTIONS // PUBLIC FUNCTIONS
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light); ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light, Camera &camera);
#define LIGHT_H #define LIGHT_H

View File

@ -32,6 +32,18 @@ inline Vector operator-(Vector const &v)
return result; return result;
} }
// v1 - v2
inline Vector operator-(Vector const &v1, Vector const &v2)
{
Vector result;
result.x = v1.x - v2.x;
result.y = v1.y - v2.y;
result.z = v1.z - v2.z;
return result;
}
// v1 + v2 // v1 + v2
inline Vector operator+(Vector const &v1, Vector const &v2) inline Vector operator+(Vector const &v1, Vector const &v2)
{ {

View File

@ -64,8 +64,8 @@ int EngineInit(char *objFilename, char *mtlFilename)
// Mesh configuration // Mesh configuration
mesh.position.z = 125; mesh.position.z = 175;
mesh.position.y = -125; mesh.position.y = -175;
mesh.scale = 1.0f; mesh.scale = 1.0f;
@ -152,29 +152,29 @@ static void CheckInputs(uint32_t input)
if (CHECK_BIT(input, ROTATE_X_POS)) if (CHECK_BIT(input, ROTATE_X_POS))
{ {
mesh.rotation.x += .10; mesh.position.x += 10;
} }
else if (CHECK_BIT(input, ROTATE_X_NEG)) else if (CHECK_BIT(input, ROTATE_X_NEG))
{ {
mesh.rotation.x -= .10; mesh.position.x -= 10;
} }
if (CHECK_BIT(input, ROTATE_Y_POS)) if (CHECK_BIT(input, ROTATE_Y_POS))
{ {
mesh.rotation.y += .10; mesh.position.y += 10;
} }
else if (CHECK_BIT(input, ROTATE_Y_NEG)) else if (CHECK_BIT(input, ROTATE_Y_NEG))
{ {
mesh.rotation.y -= .10; mesh.position.y -= 10;
} }
if (CHECK_BIT(input, ROTATE_Z_POS)) if (CHECK_BIT(input, ROTATE_Z_POS))
{ {
mesh.rotation.z += .10; mesh.position.z += 10;
} }
else if (CHECK_BIT(input, ROTATE_Z_NEG)) else if (CHECK_BIT(input, ROTATE_Z_NEG))
{ {
mesh.rotation.z -= .10; mesh.position.z -= 10;
} }
if (CHECK_BIT(input, SCALE_UP)) if (CHECK_BIT(input, SCALE_UP))
@ -338,7 +338,7 @@ static void LightMesh(void)
{ {
Vertex &vert = verts.data[face.vertIndex[i]]; Vertex &vert = verts.data[face.vertIndex[i]];
vert.color = ComputeLight(vert, material, light); vert.color = ComputeLight(vert, material, light, camera);
} }
} }
} }

View File

@ -1,45 +1,49 @@
#include "camera.h"
#include "color.h" #include "color.h"
#include "light.h" #include "light.h"
// PRIVATE PROTOTYPES // PRIVATE PROTOTYPES
static ColorF32 ComputeAmbientLight( static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity); Material &material, ColorF32 &intensity);
static ColorF32 ComputeDiffuseLight( static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity, Material &material, ColorF32 &intensity, Vertex &vert, Light &light);
Point &vertPosition, Vector &vertNormal,
Point &lightPosition); static ColorF32 ComputeSpecularLight(
Material &material, ColorF32 &intensity, Vertex &vert, Light &light,
Camera &camera);
// PUBLIC FUNCTIONS // PUBLIC FUNCTIONS
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light) ColorF32 ComputeLight(
Vertex &vert, Material &material, Light &light, Camera &camera)
{ {
// Distance from light to vertex // Distance from light to vertex
Vector direction = light.position - vert.point; Vector direction = light.position - vert.point;
float distance = VectorLength(direction); float distance = VectorLength(direction);
// Intensity is a function of the falloff factors and the distance // Point light intensity is a function of the falloff factors and the distance
ColorF32 intensity = ColorF32 intensity =
(light.intensity * light.color) (light.intensity * light.color)
/ (light.falloffConstant + light.falloffLinear * distance); / (light.falloffConstant + light.falloffLinear * distance);
// Compute ambient light // Compute ambient light
ColorF32 ambientLight = ComputeAmbientLight( ColorF32 ambientLight = ComputeAmbientLight(material, intensity);
material.ambient, intensity);
// Compute diffuse light // Compute diffuse light
ColorF32 diffuseLight = ComputeDiffuseLight( ColorF32 diffuseLight = ComputeDiffuseLight(material, intensity, vert, light);
material.diffuse, intensity,
vert.point, vert.normal,
light.position); // Compute specular light
ColorF32 specularLight = ComputeSpecularLight(material, intensity, vert, light, camera);
// Total light is sum of all lights // Total light is sum of all lights
ColorF32 result = ambientLight + diffuseLight; ColorF32 result = ambientLight + diffuseLight + specularLight;
return result; return result;
@ -48,29 +52,55 @@ ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light)
// PRIVATE FUNCTIONS // PRIVATE FUNCTIONS
static ColorF32 ComputeAmbientLight( static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity) Material &material, ColorF32 &intensity)
{ {
ColorF32 result; // light = Kd * I
ColorF32 result = material.ambient * intensity;
result = surfaceReflectivity * lightIntensity;
return result; return result;
} }
static ColorF32 ComputeDiffuseLight( static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity, Material &material, ColorF32 &intensity, Vertex &vert, Light &light)
Point &vertPosition, Vector &vertNormal,
Point &lightPosition)
{ {
// Light is a function of the position of the light source and the surface // Vector from the light to the vertex
Vector direction = lightPosition - vertPosition; Vector direction = light.position - vert.point;
VectorNormalize(direction); VectorNormalize(direction);
float normalDotDirection = VectorDot(vert.normal, direction);
float dot = VectorDot(vertNormal, direction);
ColorF32 result = surfaceReflectivity * lightIntensity * dot; // 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; return result;
} }