use LightSource instead for colors!

This commit is contained in:
2026-01-29 20:18:31 +01:00
parent 3f1c59b509
commit 45a62a0aeb
2 changed files with 44 additions and 21 deletions
+12 -7
View File
@@ -4,7 +4,13 @@ in layout(location = 0) vec3 normal;
in layout(location = 1) vec2 textureCoordinates;
in layout(location = 2) vec3 worldPositions;
uniform vec3 lightPositions[3];
struct LightSource {
vec3 position;
vec3 color;
};
uniform LightSource lights[3];
uniform vec3 cameraPosition;
uniform vec3 ballPosition;
@@ -21,7 +27,6 @@ vec3 reject(vec3 from, vec3 onto) {
}
const vec3 objectColor = vec3(1.0, 1.0, 1.0);
const vec3 lightColor = vec3(0.5, 0.5, 0.5);
const float ambientStrength = 0.1;
const float specularStrength = 0.5;
@@ -36,24 +41,24 @@ void main()
vec3 norm = normalize(normal);
vec3 viewDir = normalize(cameraPosition - worldPositions);
vec3 ambient = ambientStrength * lightColor * objectColor;
vec3 ambient = ambientStrength * vec3(1.0, 1.0, 1.0) * objectColor;
vec3 result = ambient;
for (int i = 0; i < 3; i++) {
vec3 lightVector = lightPositions[i] - worldPositions;
vec3 lightVector = lights[i].position - worldPositions;
vec3 lightDir = normalize(lightVector);
vec3 fragToBall = lightPositions[i] - ballPosition;
vec3 fragToBall = lights[i].position - ballPosition;
float d = length(lightVector);
float attenuation = 1.0 / (la + d * lb + d * d * lc);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
vec3 diffuse = diff * lights[i].color;
vec3 halfwayDir = normalize(lightDir + viewDir); // little optimization (blinn-phong)
float spec = pow(max(dot(norm, halfwayDir), 0.0), shininess);
vec3 specular = specularStrength * spec * lightColor;
vec3 specular = specularStrength * spec * lights[i].color;
// the ball's light is put inside it, thus it would cast a shadow all over the scene.
// to counter-act this, we can simply exclude it. i should instead move the light.
+32 -14
View File
@@ -2,6 +2,7 @@
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <SFML/Audio/SoundBuffer.hpp>
#include <string>
#include <utilities/shader.hpp>
#include <glm/vec3.hpp>
#include <iostream>
@@ -15,6 +16,7 @@
#include <fmt/format.h>
#include <vector>
#include "gamelogic.h"
#include "glm/detail/qualifier.hpp"
#include "glm/ext/vector_float3.hpp"
#include "glm/matrix.hpp"
#include "sceneGraph.hpp"
@@ -41,8 +43,12 @@ SceneNode* boxNode;
SceneNode* ballNode;
SceneNode* padNode;
struct LightSource {
glm::vec3 position;
glm::vec3 color;
};
std::vector<SceneNode*> lightNodes;
std::vector<glm::vec3> lightCoords;
std::vector<LightSource> lights;
glm::vec3 cameraPosition;
@@ -98,12 +104,6 @@ void mouseCallback(GLFWwindow* window, double x, double y) {
glfwSetCursorPos(window, windowWidth / 2, windowHeight / 2);
}
//// A few lines to help you if you've never used c++ structs
// struct LightSource {
// bool a_placeholder_value;
// };
// LightSource lightSources[/*Put number of light sources you want here*/];
void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
buffer = new sf::SoundBuffer();
if (!buffer->loadFromFile("../res/Hall of the Mountain King.ogg")) {
@@ -172,7 +172,6 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
getTimeDeltaSeconds();
std::cout << fmt::format("Initialized scene with {} SceneNodes.", totalChildren(rootNode)) << std::endl;
@@ -364,10 +363,21 @@ void updateFrame(GLFWwindow* window) {
updateNodeTransformations(rootNode, VP, glm::mat4(1.0f)); // Pass identity for initial model matrix
lightCoords.clear();
for (auto* light : lightNodes) {
lightCoords.push_back(light->worldPosition);
lights.clear();
for (auto* lightNode : lightNodes) {
LightSource light;
light.position = lightNode->worldPosition;
if (lightNode->lightIdx == 0) {
light.color = glm::vec3(1.0f, 0.0f, 0.0f); // Warm white (ceiling)
} else if (lightNode->lightIdx == 1) {
light.color = glm::vec3(0.0f, 1.0f, 0.0f); // Cool white (pad)
} else {
light.color = glm::vec3(0.0f, 0.0f, 1.0f); // Orange (ball)
}
lights.push_back(light);
}
}
void updateNodeTransformations(SceneNode* node, glm::mat4 transformationThusFar, glm::mat4 modelMatrixThusFar) {
@@ -403,15 +413,23 @@ void renderNode(SceneNode* node) {
glUniformMatrix4fv(4, 1, GL_FALSE, glm::value_ptr(node->modelMatrix));
glUniformMatrix3fv(5, 1, GL_FALSE, glm::value_ptr(node->normalMatrix));
GLint lightPosLoc = shader->getUniformFromName("lightPositions");
glUniform3fv(lightPosLoc, 3, glm::value_ptr(lightCoords[0]));
GLint cameraPosLoc = shader->getUniformFromName("cameraPosition");
glUniform3fv(cameraPosLoc, 1, glm::value_ptr(cameraPosition));
GLint ballPosLoc = shader->getUniformFromName("ballPosition");
glUniform3fv(ballPosLoc, 1, glm::value_ptr(ballPosition));
for (int i = 0; i < lights.size(); i++) {
std::string posName = "lights[" + std::to_string(i) + "].position";
std::string colorName = "lights[" + std::to_string(i) + "].color";
GLint posLoc = shader->getUniformFromName(posName.c_str());
GLint colorLoc = shader->getUniformFromName(colorName.c_str());
glUniform3fv(posLoc, 1, glm::value_ptr(lights[i].position));
glUniform3fv(colorLoc, 1, glm::value_ptr(lights[i].color));
}
switch(node->nodeType) {
case GEOMETRY:
if(node->vertexArrayObjectID != -1) {