Add specular lighting
This commit is contained in:
parent
e87546c8b1
commit
abf9e8fa7c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue