Modify lighting to use a point light
This commit is contained in:
		
							parent
							
								
									e29ad8b418
								
							
						
					
					
						commit
						b3991a4651
					
				
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -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
 | 
							   transform.h util.h vec.h
 | 
				
			||||||
HEADERS = $(patsubst %,$(INCLUDE_DIR)/%,$(_HEADERS))
 | 
					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))
 | 
					OBJS = $(patsubst %,$(BUILD_DIR)/%,$(_OBJS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS)
 | 
					$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,18 +20,6 @@ struct ColorU32
 | 
				
			||||||
struct ColorF32
 | 
					struct ColorF32
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    float b, g, r, a;
 | 
					    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;
 | 
					    ColorF32 result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    result.b = MIN((c1.b + c2.b), 1.0f);
 | 
					    result.b = c1.b + c2.b;
 | 
				
			||||||
    result.g = MIN((c1.g + c2.g), 1.0f);
 | 
					    result.g = c1.g + c2.g;
 | 
				
			||||||
    result.r = MIN((c1.r + c2.r), 1.0f);
 | 
					    result.r = c1.r + c2.r;
 | 
				
			||||||
    result.a = MIN((c1.a + c2.a), 1.0f);
 | 
					    result.a = c1.a + c2.a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -54,7 +42,7 @@ inline ColorF32 &operator+=(ColorF32 &c1, ColorF32 c2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    c1 = c1 + c2;
 | 
					    c1 = c1 + c2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return(c1);
 | 
					    return c1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// c * f
 | 
					// c * f
 | 
				
			||||||
| 
						 | 
					@ -62,10 +50,10 @@ inline ColorF32 operator*(ColorF32 c, float f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ColorF32 result;
 | 
					    ColorF32 result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    result.b = MIN((f * c.b), 1.0f);
 | 
					    result.b = f * c.b;
 | 
				
			||||||
    result.g = MIN((f * c.g), 1.0f);
 | 
					    result.g = f * c.g;
 | 
				
			||||||
    result.r = MIN((f * c.r), 1.0f);
 | 
					    result.r = f * c.r;
 | 
				
			||||||
    result.a = MIN((f * c.a), 1.0f);
 | 
					    result.a = f * c.a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -80,6 +68,61 @@ inline ColorF32 operator*(float f, ColorF32 c)
 | 
				
			||||||
    return result;
 | 
					    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
 | 
					#define COLOR_H
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GEOMETRY CONFIGURATION
 | 
					// GEOMETRY CONFIGURATION
 | 
				
			||||||
#define FACE_LIMIT (30000)
 | 
					#define FACE_LIMIT (30000)
 | 
				
			||||||
#define MATERIAL_LIMIT (10)
 | 
					#define MATERIAL_LIMIT (5)
 | 
				
			||||||
#define TEXTURE_SIZE_LIMIT (1024)
 | 
					#define TEXTURE_SIZE_LIMIT (1024)
 | 
				
			||||||
#define VERTEX_LIMIT (20000)
 | 
					#define VERTEX_LIMIT (20000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,47 +2,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "color.h"
 | 
					#include "color.h"
 | 
				
			||||||
#include "vec.h"
 | 
					#include "geometry.h"
 | 
				
			||||||
#include <cstdint>
 | 
					#include "point.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// STRUCTURES
 | 
					// STRUCTURES
 | 
				
			||||||
struct LightAmbient
 | 
					struct Light
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    inline ColorF32 ComputeColor(ColorF32 reflectivity)
 | 
					    Point position;
 | 
				
			||||||
    {
 | 
					    ColorF32 color;
 | 
				
			||||||
        ColorF32 result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        result = reflectivity * intensity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    float intensity;
 | 
					    float intensity;
 | 
				
			||||||
 | 
					    float falloffConstant;
 | 
				
			||||||
 | 
					    float falloffLinear;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct LightDiffuse
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    inline ColorF32 ComputeColor(ColorF32 reflectivity, Vector normal)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ColorF32 result;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float dot = Vector::Dot(normal, direction);
 | 
					// PUBLIC FUNCTIONS
 | 
				
			||||||
 | 
					ColorF32 ComputeLight(Vertex &vert, Material &material, Light &light);
 | 
				
			||||||
        result = reflectivity * intensity * dot;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    float intensity;
 | 
					 | 
				
			||||||
    Vector direction;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct LightList
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    LightAmbient ambient;
 | 
					 | 
				
			||||||
    LightDiffuse diffuse;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LIGHT_H
 | 
					#define LIGHT_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@
 | 
				
			||||||
// GLOBALS
 | 
					// GLOBALS
 | 
				
			||||||
static Mesh mesh;
 | 
					static Mesh mesh;
 | 
				
			||||||
static Camera camera;
 | 
					static Camera camera;
 | 
				
			||||||
static LightList lights;
 | 
					static Light light;
 | 
				
			||||||
static VertexList localVerts;
 | 
					static VertexList localVerts;
 | 
				
			||||||
static VertexList transVerts;
 | 
					static VertexList transVerts;
 | 
				
			||||||
static FaceList localFaces;
 | 
					static FaceList localFaces;
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ static void ComputeNormals(void);
 | 
				
			||||||
static void ClearDepthBuffer(Engine_Buffer &buffer);
 | 
					static void ClearDepthBuffer(Engine_Buffer &buffer);
 | 
				
			||||||
static void TransformToClipSpace(void);
 | 
					static void TransformToClipSpace(void);
 | 
				
			||||||
static void TransformToScreenSpace(void);
 | 
					static void TransformToScreenSpace(void);
 | 
				
			||||||
static void ComputeLighting(void);
 | 
					static void LightMesh(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PUBLIC FUNCTIONS
 | 
					// PUBLIC FUNCTIONS
 | 
				
			||||||
| 
						 | 
					@ -68,15 +68,17 @@ int Engine_Init(char *objFilename, char *mtlFilename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Mesh configuration
 | 
					    // Mesh configuration
 | 
				
			||||||
    mesh.position.z = 50;
 | 
					    mesh.position.z = 125;
 | 
				
			||||||
    mesh.position.y = -50;
 | 
					    mesh.position.y = -125;
 | 
				
			||||||
    mesh.scale = 1.0f;
 | 
					    mesh.scale = 1.0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Light configuration
 | 
					    // Light configuration
 | 
				
			||||||
    lights.ambient.intensity = 1.0f;
 | 
					    light.position = Point(-100.0f, 200.0f, 0.0f);
 | 
				
			||||||
    lights.diffuse.intensity = 1.0f;
 | 
					    light.color = {1.0f, 1.0f, 1.0f, 1.0f};
 | 
				
			||||||
    lights.diffuse.direction = Vector(1.0f, 1.0f, 1.0f);
 | 
					    light.intensity = 2.0f;
 | 
				
			||||||
 | 
					    light.falloffConstant = 1.0f;
 | 
				
			||||||
 | 
					    light.falloffLinear = 0.001f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Transformation matrices that do not change
 | 
					    // Transformation matrices that do not change
 | 
				
			||||||
| 
						 | 
					@ -106,7 +108,7 @@ void Engine_Render(Engine_Buffer &buffer, uint32_t input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Light vertices and/or faces
 | 
					    // Light vertices and/or faces
 | 
				
			||||||
    ComputeLighting();
 | 
					    LightMesh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Transform vertices to screen space
 | 
					    // Transform vertices to screen space
 | 
				
			||||||
| 
						 | 
					@ -127,29 +129,29 @@ static void CheckInputs(uint32_t input)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (CHECK_BIT(input, TRANSLATE_X_POS))
 | 
					    if (CHECK_BIT(input, TRANSLATE_X_POS))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.x += 10;
 | 
					        light.position.x += 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (CHECK_BIT(input, TRANSLATE_X_NEG))
 | 
					    else if (CHECK_BIT(input, TRANSLATE_X_NEG))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.x -= 10;
 | 
					        light.position.x -= 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CHECK_BIT(input, TRANSLATE_Z_POS))
 | 
					    if (CHECK_BIT(input, TRANSLATE_Z_POS))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.z += 10;
 | 
					        light.position.z += 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (CHECK_BIT(input, TRANSLATE_Z_NEG))
 | 
					    else if (CHECK_BIT(input, TRANSLATE_Z_NEG))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.z -= 10;
 | 
					        light.position.z -= 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CHECK_BIT(input, TRANSLATE_Y_POS))
 | 
					    if (CHECK_BIT(input, TRANSLATE_Y_POS))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.y += 10;
 | 
					        light.position.y += 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (CHECK_BIT(input, TRANSLATE_Y_NEG))
 | 
					    else if (CHECK_BIT(input, TRANSLATE_Y_NEG))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mesh.position.y -= 10;
 | 
					        light.position.y -= 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CHECK_BIT(input, ROTATE_X_POS))
 | 
					    if (CHECK_BIT(input, ROTATE_X_POS))
 | 
				
			||||||
| 
						 | 
					@ -181,11 +183,15 @@ static void CheckInputs(uint32_t input)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (CHECK_BIT(input, SCALE_UP))
 | 
					    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))
 | 
					    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)
 | 
					    for (size_t f = 0; f < transFaces.size; ++f)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Face &face = transFaces.data[f];
 | 
					        Face &face = transFaces.data[f];
 | 
				
			||||||
        Material &material = materials.data[face.materialIndex];
 | 
					        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
 | 
					        // Gouraud shading
 | 
				
			||||||
        for (int i = 0; i < 3; ++i)
 | 
					        for (int i = 0; i < 3; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Vertex &vert = transVerts.data[face.vertIndex[i]];
 | 
					            Vertex &vert = transVerts.data[face.vertIndex[i]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vert.color =
 | 
					            vert.color = ComputeLight(vert, material, light);
 | 
				
			||||||
                lights.ambient.ComputeColor(material.ambient)
 | 
					 | 
				
			||||||
                + lights.diffuse.ComputeColor(material.diffuse, vert.normal);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,11 +187,16 @@ void RenderMesh(
 | 
				
			||||||
                        + (barycenter[1] * c1)
 | 
					                        + (barycenter[1] * c1)
 | 
				
			||||||
                        + (barycenter[2] * c2);
 | 
					                        + (barycenter[2] * c2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // Ensure no color channel exceeds 1.0
 | 
				
			||||||
 | 
					                    ScaleColor(shading);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // Light the texture
 | 
				
			||||||
                    color.b *= shading.b;
 | 
					                    color.b *= shading.b;
 | 
				
			||||||
                    color.g *= shading.g;
 | 
					                    color.g *= shading.g;
 | 
				
			||||||
                    color.r *= shading.r;
 | 
					                    color.r *= shading.r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Interpolate 1/z for the z-buffer
 | 
					                    // Interpolate 1/z for the z-buffer
 | 
				
			||||||
                    float zInv =
 | 
					                    float zInv =
 | 
				
			||||||
                        1.0f /
 | 
					                        1.0f /
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue