ADD: Phong Lighting model

This commit is contained in:
sebastian 2026-08-02 10:17:38 +02:00
parent 86e15013d0
commit 6b011860fc
15 changed files with 104 additions and 16 deletions

View File

@ -136,6 +136,8 @@ add_library(Engine STATIC
engine/src/loader/models/MeshSection.h
engine/src/loader/assets/AssetManager.cpp
engine/src/loader/assets/AssetManager.h
engine/src/renderer/entities/PointLight.cpp
engine/src/renderer/entities/PointLight.h
)
target_include_directories(Engine PUBLIC engine/src)
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image)

View File

@ -1,12 +1,35 @@
#version 460 core
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 worldPos;
uniform sampler2D textureSampler;
uniform sampler2D diffuseSampler;
uniform float opacity;
uniform float shininess;
uniform vec3 lightPosition;
uniform vec3 lightColor;
uniform vec3 cameraPosition;
out vec4 fragColor;
void main() {
vec4 texColor = texture(textureSampler, pass_textureCoords);
fragColor = vec4(texColor.rgb, texColor.a * opacity);
vec3 normal = normalize(surfaceNormal);
vec3 lightDir = normalize(lightPosition - worldPos);
vec3 camDir = normalize(cameraPosition - worldPos);
vec3 reflectDir = reflect(-lightDir, normal);
vec3 ambient = 0.1 * lightColor;
float diff = max(dot(normal, lightDir) , 0.0f);
vec3 diffuse = diff * lightColor;
float spec = pow(max(dot(camDir, reflectDir), 0.0), max(shininess, 1.0f));
vec3 specular = 0.5 * spec * lightColor;
vec4 texColor = texture(diffuseSampler, pass_textureCoords);
fragColor = vec4((ambient + diffuse + specular) * texColor.rgb, texColor.a * opacity);
}

View File

@ -9,11 +9,14 @@ uniform mat4 viewMatrix;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 worldPos;
void main() {
vec4 worldPosition = transformationMatrix * vec4(position, 1.0f);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal , 0.f)).xyz;
surfaceNormal = mat3(transpose(inverse(transformationMatrix))) * normal;
worldPos = worldPosition.xyz;
}

View File

@ -14,7 +14,7 @@
engine::RawModelBundle engine::ModelImporter::importFromFile(const std::string& objPath, ModelSplitPolicy policy) {
tinyobj::ObjReaderConfig config;
config.mtl_search_path = std::filesystem::path(objPath).parent_path().string();
config.triangulate = true; // GL braucht Dreiecke, keine n-Ecke
config.triangulate = false; // GL braucht Dreiecke, keine n-Ecke
tinyobj::ObjReader reader;
if (!reader.ParseFromFile(objPath, config)) {

View File

@ -9,6 +9,7 @@
void engine::MeshRenderSystem::update(engine::EntityRegistry &registry, engine::RenderQueue &renderQueue) {
renderState.apply();
auto transforms = registry.getPool<engine::TransformComponent>();
auto meshes = registry.getPool<engine::MeshComponent>();

View File

@ -5,12 +5,15 @@
#ifndef COLORRACE_MESHRENDERSYSTEM_H
#define COLORRACE_MESHRENDERSYSTEM_H
#include "RenderSystem.h"
#include "utils/openglWrapper/GLRenderState.h"
namespace engine {
class MeshRenderSystem : public engine::RenderSystem {
public:
void update(engine::EntityRegistry &registry, engine::RenderQueue &renderQueue) override;
private:
GLRenderState renderState;
};
}

View File

@ -4,10 +4,14 @@
#include "MeshRenderer.h"
void engine::MeshRenderer::render(RenderQueue &queue, const Camera &camera) {
#include "entities/PointLight.h"
void engine::MeshRenderer::render(RenderQueue &queue, const Camera &camera, const PointLight& light) {
m_shader->start();
m_shader->loadViewMatrix(camera.getViewMatrix());
m_shader->loadProjectionMatrix(camera.getProjectionMatrix());
m_shader->loadCameraPosition(camera.getPosition());
m_shader->loadLight(light.position, light.color);
for (const auto&[mesh, transformationMatrix] : queue.getRenderCommands()) {
m_shader->loadTransformationMatrix(transformationMatrix);

View File

@ -6,6 +6,7 @@
#define COLORRACE_MESHRENDERER_H
#include "RenderQueue.h"
#include "entities/Camera.h"
#include "entities/PointLight.h"
#include "shader/StaticShader.h"
@ -13,7 +14,7 @@ namespace engine {
class MeshRenderer {
public:
MeshRenderer() : m_shader(std::make_unique<StaticShader>()) {}
void render(RenderQueue& queue, const Camera& camera);
void render(RenderQueue& queue, const Camera& camera, const PointLight& light);
private:
std::unique_ptr<StaticShader> m_shader;
};

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 02.08.26.
//
#include "PointLight.h"

View File

@ -0,0 +1,17 @@
//
// Created by sebastian on 02.08.26.
//
#ifndef COLORRACE_POINTLIGHT_H
#define COLORRACE_POINTLIGHT_H
#include "glm/vec3.hpp"
namespace engine {
struct PointLight {
glm::vec3 position;
glm::vec3 color;
};
}
#endif //COLORRACE_POINTLIGHT_H

View File

@ -19,7 +19,11 @@ namespace engine {
std::ref(transformationMatrix),
std::ref(projectionMatrix),
std::ref(viewMatrix),
std::ref(opacity)
std::ref(opacity),
std::ref(lightPosition),
std::ref(lightColor),
std::ref(cameraPosition),
std::ref(shininess),
});
};
@ -37,7 +41,16 @@ namespace engine {
void loadMaterial(const Material& material) {
//shininess.load(material.getShininess());
opacity.load(material.getOpacity());
//opacity.load(material.getOpacity());
}
void loadLight(const glm::vec3& position, const glm::vec3& color) {
lightPosition.load(position);
lightColor.load(color);
}
void loadCameraPosition(const glm::vec3& position) {
cameraPosition.load(position);
}
private:
engine::UniformValue<glm::mat4> transformationMatrix{"transformationMatrix"};
@ -45,6 +58,9 @@ namespace engine {
engine::UniformValue<glm::mat4> viewMatrix{"viewMatrix"};
engine::UniformValue<float> shininess{"shininess"};
engine::UniformValue<float> opacity{"opacity"};
engine::UniformValue<glm::vec3> lightPosition{"lightPosition"};
engine::UniformValue<glm::vec3> lightColor{"lightColor"};
engine::UniformValue<glm::vec3> cameraPosition{"cameraPosition"};
};
}

View File

@ -26,6 +26,15 @@ void GameLayer::onDetach() {
void GameLayer::onUpdate() {
Layer::onUpdate();
auto transformComponentPool = m_entityRegistry.getPool<TransformComponent>();
for (const auto& [entity, transform] : transformComponentPool) {
m_entityRegistry.removeComponent<TransformComponent>(entity);
const auto updatedTransform = TransformComponent({0,0,0}, {0, transform.m_rotation.y + 1,0}, {1,1,1});
m_entityRegistry.addComponent<TransformComponent>(entity, updatedTransform);
}
}
void GameLayer::onRender() {
@ -33,5 +42,5 @@ void GameLayer::onRender() {
MeshRenderSystem meshRenderSystem;
meshRenderSystem.update(m_entityRegistry, m_renderQueue);
m_renderer->render(m_renderQueue, *m_camera);
m_renderer->render(m_renderQueue, *m_camera, *m_pointLight);
}

View File

@ -15,8 +15,8 @@
class GameLayer: public engine::Layer {
public:
GameLayer(engine::EntityRegistry& entityRegistry, std::shared_ptr<engine::Camera> cam)
: m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique<engine::MeshRenderer>()) {}
GameLayer(engine::EntityRegistry& entityRegistry, std::shared_ptr<engine::Camera> cam, std::shared_ptr<engine::PointLight> light)
: m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique<engine::MeshRenderer>()), m_pointLight(light) {}
void onAttach() override;
void onDetach() override;
void onUpdate() override;
@ -25,6 +25,7 @@ private:
engine::GLRenderState m_renderState;
engine::RenderQueue m_renderQueue;
engine::EntityRegistry& m_entityRegistry;
std::shared_ptr<engine::PointLight> m_pointLight;
std::shared_ptr<engine::Camera> m_camera;
std::unique_ptr<engine::MeshRenderer> m_renderer;
};

View File

@ -8,10 +8,12 @@
#include "ecs/standardComponents/MeshComponent.h"
#include "ecs/standardComponents/TransformComponent.h"
GameScene::GameScene() : Scene(), m_camera(std::make_unique<engine::Camera>()) {}
GameScene::GameScene() : Scene(), m_camera(std::make_unique<engine::Camera>()) {
m_pointLight = std::make_shared<engine::PointLight>(glm::vec3(.0f, .0f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f));
}
void GameScene::onEnter() {
addLayer(std::make_unique<GameLayer>(entityRegistry, m_camera));
addLayer(std::make_unique<GameLayer>(entityRegistry, m_camera, m_pointLight));
m_camera->setPosition({0.0f, 0.0f, 5.0f});
m_camera->setYaw(0.0f);
@ -38,4 +40,4 @@ std::vector<engine::AssetRequest> GameScene::getRequiredAssets() const {
std::vector<engine::AssetRequest> requests;
requests.emplace_back(engine::ModelRequest{"pawn", "assets/models/chess.obj", engine::ModelSplitPolicy::Combined});
return requests;
};
}

View File

@ -5,6 +5,7 @@
#ifndef COLORRACE_GAMESCENE_H
#define COLORRACE_GAMESCENE_H
#include "layer/Scene.h"
#include "renderer/entities/PointLight.h"
class GameScene : public engine::Scene {
@ -15,7 +16,7 @@ public:
std::vector<engine::AssetRequest> getRequiredAssets() const override;
private:
std::shared_ptr<engine::Camera> m_camera;
std::shared_ptr<engine::PointLight> m_pointLight;
};