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
#include "camera.h"
#include "color.h"
#include "geometry.h"
#include "point.h"
@ -18,7 +19,7 @@ struct Light
// PUBLIC FUNCTIONS
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light);
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light, Camera &camera);
#define LIGHT_H

View File

@ -32,6 +32,18 @@ inline Vector operator-(Vector const &v)
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
inline Vector operator+(Vector const &v1, Vector const &v2)
{

View File

@ -64,8 +64,8 @@ int EngineInit(char *objFilename, char *mtlFilename)
// Mesh configuration
mesh.position.z = 125;
mesh.position.y = -125;
mesh.position.z = 175;
mesh.position.y = -175;
mesh.scale = 1.0f;
@ -152,29 +152,29 @@ static void CheckInputs(uint32_t input)
if (CHECK_BIT(input, ROTATE_X_POS))
{
mesh.rotation.x += .10;
mesh.position.x += 10;
}
else if (CHECK_BIT(input, ROTATE_X_NEG))
{
mesh.rotation.x -= .10;
mesh.position.x -= 10;
}
if (CHECK_BIT(input, ROTATE_Y_POS))
{
mesh.rotation.y += .10;
mesh.position.y += 10;
}
else if (CHECK_BIT(input, ROTATE_Y_NEG))
{
mesh.rotation.y -= .10;
mesh.position.y -= 10;
}
if (CHECK_BIT(input, ROTATE_Z_POS))
{
mesh.rotation.z += .10;
mesh.position.z += 10;
}
else if (CHECK_BIT(input, ROTATE_Z_NEG))
{
mesh.rotation.z -= .10;
mesh.position.z -= 10;
}
if (CHECK_BIT(input, SCALE_UP))
@ -338,7 +338,7 @@ static void LightMesh(void)
{
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 "light.h"
// PRIVATE PROTOTYPES
static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity);
Material &material, ColorF32 &intensity);
static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity,
Point &vertPosition, Vector &vertNormal,
Point &lightPosition);
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)
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);
// 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 =
(light.intensity * light.color)
/ (light.falloffConstant + light.falloffLinear * distance);
// Compute ambient light
ColorF32 ambientLight = ComputeAmbientLight(
material.ambient, intensity);
ColorF32 ambientLight = ComputeAmbientLight(material, intensity);
// Compute diffuse light
ColorF32 diffuseLight = ComputeDiffuseLight(
material.diffuse, intensity,
vert.point, vert.normal,
light.position);
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;
ColorF32 result = ambientLight + diffuseLight + specularLight;
return result;
@ -48,29 +52,55 @@ ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light)
// PRIVATE FUNCTIONS
static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity)
Material &material, ColorF32 &intensity)
{
ColorF32 result;
result = surfaceReflectivity * lightIntensity;
// light = Kd * I
ColorF32 result = material.ambient * intensity;
return result;
}
static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity,
Point &vertPosition, Vector &vertNormal,
Point &lightPosition)
Material &material, ColorF32 &intensity, Vertex &vert, Light &light)
{
// Light is a function of the position of the light source and the surface
Vector direction = lightPosition - vertPosition;
// Vector from the light to the vertex
Vector direction = light.position - vert.point;
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;
}