1
0
Fork 0

Modify lighting to use a point light

This commit is contained in:
Austin Morlan 2018-09-18 20:02:12 -07:00
parent e29ad8b418
commit b3991a4651
Signed by: austin
GPG Key ID: FD6B27654AF5E348
7 changed files with 183 additions and 81 deletions

View File

@ -44,7 +44,7 @@ _HEADERS = camera.h color.h engine.h geometry.h light.h loader.h platform.h poin
transform.h util.h vec.h
HEADERS = $(patsubst %,$(INCLUDE_DIR)/%,$(_HEADERS))
_OBJS = engine.o geometry.o loader.o main.o platform.o transform.o
_OBJS = engine.o geometry.o light.o loader.o main.o platform.o transform.o
OBJS = $(patsubst %,$(BUILD_DIR)/%,$(_OBJS))
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS)

View File

@ -20,18 +20,6 @@ struct ColorU32
struct ColorF32
{
float b, g, r, a;
static inline ColorU32 ConvertToU32(ColorF32 c)
{
ColorU32 result;
result.b = (uint8_t)(c.b * 255);
result.g = (uint8_t)(c.g * 255);
result.r = (uint8_t)(c.r * 255);
result.a = (uint8_t)(c.a * 255);
return result;
}
};
@ -41,10 +29,10 @@ inline ColorF32 operator+(ColorF32 c1, ColorF32 c2)
{
ColorF32 result;
result.b = MIN((c1.b + c2.b), 1.0f);
result.g = MIN((c1.g + c2.g), 1.0f);
result.r = MIN((c1.r + c2.r), 1.0f);
result.a = MIN((c1.a + c2.a), 1.0f);
result.b = c1.b + c2.b;
result.g = c1.g + c2.g;
result.r = c1.r + c2.r;
result.a = c1.a + c2.a;
return result;
}
@ -54,7 +42,7 @@ inline ColorF32 &operator+=(ColorF32 &c1, ColorF32 c2)
{
c1 = c1 + c2;
return(c1);
return c1;
}
// c * f
@ -62,10 +50,10 @@ inline ColorF32 operator*(ColorF32 c, float f)
{
ColorF32 result;
result.b = MIN((f * c.b), 1.0f);
result.g = MIN((f * c.g), 1.0f);
result.r = MIN((f * c.r), 1.0f);
result.a = MIN((f * c.a), 1.0f);
result.b = f * c.b;
result.g = f * c.g;
result.r = f * c.r;
result.a = f * c.a;
return result;
}
@ -80,6 +68,61 @@ inline ColorF32 operator*(float f, ColorF32 c)
return result;
}
// c1 * c2
inline ColorF32 operator*(ColorF32 c1, ColorF32 c2)
{
ColorF32 result;
result.b = c1.b * c2.b;
result.g = c1.g * c2.g;
result.r = c1.r * c2.r;
result.a = c1.a * c2.a;
return result;
}
// c / f
inline ColorF32 operator/(ColorF32 c, float f)
{
ColorF32 result;
float invF = 1.0f / f;
result.b = c.b * invF;
result.g = c.g * invF;
result.r = c.r * invF;
result.a = c.a * invF;
return result;
}
// c /= f
inline ColorF32 &operator/=(ColorF32 &c, float f)
{
c = c / f;
return c;
}
inline void ScaleColor(ColorF32 &c)
{
float blue = MAX(c.b, 0.0f);
float green = MAX(c.g, 0.0f);
float red = MAX(c.r, 0.0f);
float alpha = MAX(c.a, 0.0f);
float max = MAX(MAX(MAX(blue,green),red),1.0f);
ColorF32 scaled = {blue, green, red, alpha};
scaled /= max;
c.b = scaled.b;
c.g = scaled.g;
c.r = scaled.r;
c.a = scaled.a;
}
#define COLOR_H
#endif

View File

@ -15,7 +15,7 @@
// GEOMETRY CONFIGURATION
#define FACE_LIMIT (30000)
#define MATERIAL_LIMIT (10)
#define MATERIAL_LIMIT (5)
#define TEXTURE_SIZE_LIMIT (1024)
#define VERTEX_LIMIT (20000)

View File

@ -2,47 +2,23 @@
#include "color.h"
#include "vec.h"
#include <cstdint>
#include "geometry.h"
#include "point.h"
// STRUCTURES
struct LightAmbient
struct Light
{
inline ColorF32 ComputeColor(ColorF32 reflectivity)
{
ColorF32 result;
result = reflectivity * intensity;
return result;
}
Point position;
ColorF32 color;
float intensity;
float falloffConstant;
float falloffLinear;
};
struct LightDiffuse
{
inline ColorF32 ComputeColor(ColorF32 reflectivity, Vector normal)
{
ColorF32 result;
float dot = Vector::Dot(normal, direction);
result = reflectivity * intensity * dot;
return result;
}
float intensity;
Vector direction;
};
struct LightList
{
LightAmbient ambient;
LightDiffuse diffuse;
};
// PUBLIC FUNCTIONS
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light);
#define LIGHT_H

View File

@ -15,7 +15,7 @@
// GLOBALS
static Mesh mesh;
static Camera camera;
static LightList lights;
static Light light;
static VertexList localVerts;
static VertexList transVerts;
static FaceList localFaces;
@ -33,7 +33,7 @@ static void ComputeNormals(void);
static void ClearDepthBuffer(Engine_Buffer &buffer);
static void TransformToClipSpace(void);
static void TransformToScreenSpace(void);
static void ComputeLighting(void);
static void LightMesh(void);
// PUBLIC FUNCTIONS
@ -68,15 +68,17 @@ int Engine_Init(char *objFilename, char *mtlFilename)
// Mesh configuration
mesh.position.z = 50;
mesh.position.y = -50;
mesh.position.z = 125;
mesh.position.y = -125;
mesh.scale = 1.0f;
// Light configuration
lights.ambient.intensity = 1.0f;
lights.diffuse.intensity = 1.0f;
lights.diffuse.direction = Vector(1.0f, 1.0f, 1.0f);
light.position = Point(-100.0f, 200.0f, 0.0f);
light.color = {1.0f, 1.0f, 1.0f, 1.0f};
light.intensity = 2.0f;
light.falloffConstant = 1.0f;
light.falloffLinear = 0.001f;
// Transformation matrices that do not change
@ -106,7 +108,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
// Light vertices and/or faces
ComputeLighting();
LightMesh();
// Transform vertices to screen space
@ -127,29 +129,29 @@ static void CheckInputs(uint32_t input)
{
if (CHECK_BIT(input, TRANSLATE_X_POS))
{
mesh.position.x += 10;
light.position.x += 10;
}
else if (CHECK_BIT(input, TRANSLATE_X_NEG))
{
mesh.position.x -= 10;
light.position.x -= 10;
}
if (CHECK_BIT(input, TRANSLATE_Z_POS))
{
mesh.position.z += 10;
light.position.z += 10;
}
else if (CHECK_BIT(input, TRANSLATE_Z_NEG))
{
mesh.position.z -= 10;
light.position.z -= 10;
}
if (CHECK_BIT(input, TRANSLATE_Y_POS))
{
mesh.position.y += 10;
light.position.y += 10;
}
else if (CHECK_BIT(input, TRANSLATE_Y_NEG))
{
mesh.position.y -= 10;
light.position.y -= 10;
}
if (CHECK_BIT(input, ROTATE_X_POS))
@ -181,11 +183,15 @@ static void CheckInputs(uint32_t input)
if (CHECK_BIT(input, SCALE_UP))
{
mesh.scale += 0.1f;
light.color.b = 0.0f;
light.color.g = 0.0f;
light.color.r = 1.0f;
}
else if (CHECK_BIT(input, SCALE_DOWN))
{
mesh.scale -= 0.1f;
light.color.b = 1.0f;
light.color.g = 1.0f;
light.color.r = 1.0f;
}
}
@ -265,25 +271,19 @@ static void TransformToScreenSpace(void)
}
}
static void ComputeLighting(void)
static void LightMesh(void)
{
for (size_t f = 0; f < transFaces.size; ++f)
{
Face &face = transFaces.data[f];
Material &material = materials.data[face.materialIndex];
// TODO: Fix weird lighting
material.ambient = {1.0,1.0,1.0,1.0};
material.diffuse = {0.5,0.5,0.5,0.5};
// Gouraud shading
for (int i = 0; i < 3; ++i)
{
Vertex &vert = transVerts.data[face.vertIndex[i]];
vert.color =
lights.ambient.ComputeColor(material.ambient)
+ lights.diffuse.ComputeColor(material.diffuse, vert.normal);
vert.color = ComputeLight(vert, material, light);
}
}
}

View File

@ -187,11 +187,16 @@ void RenderMesh(
+ (barycenter[1] * c1)
+ (barycenter[2] * c2);
// Ensure no color channel exceeds 1.0
ScaleColor(shading);
// Light the texture
color.b *= shading.b;
color.g *= shading.g;
color.r *= shading.r;
// Interpolate 1/z for the z-buffer
float zInv =
1.0f /

78
src/light.cpp Normal file
View File

@ -0,0 +1,78 @@
#include "color.h"
#include "light.h"
// PRIVATE PROTOTYPES
static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity);
static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity,
Point &vertPosition, Vector &vertNormal,
Point &lightPosition);
// PUBLIC FUNCTIONS
ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light)
{
// Distance from light to vertex
Vector d = light.position - vert.point;
float distance = d.Length();
// 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);
// Compute diffuse light
ColorF32 diffuseLight = ComputeDiffuseLight(
material.diffuse, intensity,
vert.point, vert.normal,
light.position);
// Total light is sum of all lights
ColorF32 result = ambientLight + diffuseLight;
return result;
}
// PRIVATE FUNCTIONS
static ColorF32 ComputeAmbientLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity)
{
ColorF32 result;
result = surfaceReflectivity * lightIntensity;
return result;
}
static ColorF32 ComputeDiffuseLight(
ColorF32 surfaceReflectivity, ColorF32 lightIntensity,
Point &vertPosition, Vector &vertNormal,
Point &lightPosition)
{
// Light is a function of the position of the light source and the surface
Vector direction = lightPosition - vertPosition;
direction.Normalize();
float dot = Vector::Dot(vertNormal, direction);
ColorF32 result = surfaceReflectivity * lightIntensity * dot;
return result;
}