From 6b011860fc5aa36015e9647e1644f343828b5afa Mon Sep 17 00:00:00 2001 From: sebastian Date: Sun, 2 Aug 2026 10:17:38 +0200 Subject: [PATCH] ADD: Phong Lighting model --- CMakeLists.txt | 2 ++ assets/shaders/basic.frag | 29 ++++++++++++++++++--- assets/shaders/basic.vert | 5 +++- engine/src/loader/models/ModelImporter.cpp | 2 +- engine/src/renderer/MeshRenderSystem.cpp | 1 + engine/src/renderer/MeshRenderSystem.h | 3 +++ engine/src/renderer/MeshRenderer.cpp | 6 ++++- engine/src/renderer/MeshRenderer.h | 3 ++- engine/src/renderer/entities/PointLight.cpp | 5 ++++ engine/src/renderer/entities/PointLight.h | 17 ++++++++++++ engine/src/renderer/shader/StaticShader.h | 20 ++++++++++++-- game/src/GameLayer.cpp | 11 +++++++- game/src/GameLayer.h | 5 ++-- game/src/GameScene.cpp | 8 +++--- game/src/GameScene.h | 3 ++- 15 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 engine/src/renderer/entities/PointLight.cpp create mode 100644 engine/src/renderer/entities/PointLight.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c457e82..590f039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/assets/shaders/basic.frag b/assets/shaders/basic.frag index 8143310..9091bef 100644 --- a/assets/shaders/basic.frag +++ b/assets/shaders/basic.frag @@ -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); + } \ No newline at end of file diff --git a/assets/shaders/basic.vert b/assets/shaders/basic.vert index af2015c..a87d924 100644 --- a/assets/shaders/basic.vert +++ b/assets/shaders/basic.vert @@ -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; + } \ No newline at end of file diff --git a/engine/src/loader/models/ModelImporter.cpp b/engine/src/loader/models/ModelImporter.cpp index 788aaa2..c697e5d 100644 --- a/engine/src/loader/models/ModelImporter.cpp +++ b/engine/src/loader/models/ModelImporter.cpp @@ -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)) { diff --git a/engine/src/renderer/MeshRenderSystem.cpp b/engine/src/renderer/MeshRenderSystem.cpp index 44bb1d1..a605b58 100644 --- a/engine/src/renderer/MeshRenderSystem.cpp +++ b/engine/src/renderer/MeshRenderSystem.cpp @@ -9,6 +9,7 @@ void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine::RenderQueue &renderQueue) { + renderState.apply(); auto transforms = registry.getPool(); auto meshes = registry.getPool(); diff --git a/engine/src/renderer/MeshRenderSystem.h b/engine/src/renderer/MeshRenderSystem.h index cac525c..a2cf427 100644 --- a/engine/src/renderer/MeshRenderSystem.h +++ b/engine/src/renderer/MeshRenderSystem.h @@ -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 ®istry, engine::RenderQueue &renderQueue) override; + private: + GLRenderState renderState; }; } diff --git a/engine/src/renderer/MeshRenderer.cpp b/engine/src/renderer/MeshRenderer.cpp index aff1fdb..64eb332 100644 --- a/engine/src/renderer/MeshRenderer.cpp +++ b/engine/src/renderer/MeshRenderer.cpp @@ -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); diff --git a/engine/src/renderer/MeshRenderer.h b/engine/src/renderer/MeshRenderer.h index 3f0c7bf..a25cd8e 100644 --- a/engine/src/renderer/MeshRenderer.h +++ b/engine/src/renderer/MeshRenderer.h @@ -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()) {} - void render(RenderQueue& queue, const Camera& camera); + void render(RenderQueue& queue, const Camera& camera, const PointLight& light); private: std::unique_ptr m_shader; }; diff --git a/engine/src/renderer/entities/PointLight.cpp b/engine/src/renderer/entities/PointLight.cpp new file mode 100644 index 0000000..ed6ad05 --- /dev/null +++ b/engine/src/renderer/entities/PointLight.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 02.08.26. +// + +#include "PointLight.h" diff --git a/engine/src/renderer/entities/PointLight.h b/engine/src/renderer/entities/PointLight.h new file mode 100644 index 0000000..a2566cd --- /dev/null +++ b/engine/src/renderer/entities/PointLight.h @@ -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 diff --git a/engine/src/renderer/shader/StaticShader.h b/engine/src/renderer/shader/StaticShader.h index 067ce6a..cd3dcb6 100644 --- a/engine/src/renderer/shader/StaticShader.h +++ b/engine/src/renderer/shader/StaticShader.h @@ -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 transformationMatrix{"transformationMatrix"}; @@ -45,6 +58,9 @@ namespace engine { engine::UniformValue viewMatrix{"viewMatrix"}; engine::UniformValue shininess{"shininess"}; engine::UniformValue opacity{"opacity"}; + engine::UniformValue lightPosition{"lightPosition"}; + engine::UniformValue lightColor{"lightColor"}; + engine::UniformValue cameraPosition{"cameraPosition"}; }; } diff --git a/game/src/GameLayer.cpp b/game/src/GameLayer.cpp index 96248e0..faa7833 100644 --- a/game/src/GameLayer.cpp +++ b/game/src/GameLayer.cpp @@ -26,6 +26,15 @@ void GameLayer::onDetach() { void GameLayer::onUpdate() { Layer::onUpdate(); + + auto transformComponentPool = m_entityRegistry.getPool(); + for (const auto& [entity, transform] : transformComponentPool) { + m_entityRegistry.removeComponent(entity); + + const auto updatedTransform = TransformComponent({0,0,0}, {0, transform.m_rotation.y + 1,0}, {1,1,1}); + m_entityRegistry.addComponent(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); } diff --git a/game/src/GameLayer.h b/game/src/GameLayer.h index 108f063..5e1afb6 100644 --- a/game/src/GameLayer.h +++ b/game/src/GameLayer.h @@ -15,8 +15,8 @@ class GameLayer: public engine::Layer { public: - GameLayer(engine::EntityRegistry& entityRegistry, std::shared_ptr cam) - : m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique()) {} + GameLayer(engine::EntityRegistry& entityRegistry, std::shared_ptr cam, std::shared_ptr light) + : m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique()), 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 m_pointLight; std::shared_ptr m_camera; std::unique_ptr m_renderer; }; diff --git a/game/src/GameScene.cpp b/game/src/GameScene.cpp index bc29b71..1245821 100644 --- a/game/src/GameScene.cpp +++ b/game/src/GameScene.cpp @@ -8,10 +8,12 @@ #include "ecs/standardComponents/MeshComponent.h" #include "ecs/standardComponents/TransformComponent.h" -GameScene::GameScene() : Scene(), m_camera(std::make_unique()) {} +GameScene::GameScene() : Scene(), m_camera(std::make_unique()) { + m_pointLight = std::make_shared(glm::vec3(.0f, .0f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f)); +} void GameScene::onEnter() { - addLayer(std::make_unique(entityRegistry, m_camera)); + addLayer(std::make_unique(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 GameScene::getRequiredAssets() const { std::vector requests; requests.emplace_back(engine::ModelRequest{"pawn", "assets/models/chess.obj", engine::ModelSplitPolicy::Combined}); return requests; -}; +} \ No newline at end of file diff --git a/game/src/GameScene.h b/game/src/GameScene.h index 2fef1ab..a9ddb08 100644 --- a/game/src/GameScene.h +++ b/game/src/GameScene.h @@ -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 getRequiredAssets() const override; private: std::shared_ptr m_camera; - + std::shared_ptr m_pointLight; };