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