From 4c0d737678f149a403a2d070e76a40bb6c1063b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Petter=20Sk=C3=A5lerud?= <np_skalerud@hotmail.com> Date: Sat, 23 Mar 2019 16:42:10 +0100 Subject: [PATCH] Made progress on lighting Updated submodule DMath to latest version Updated Mesh shader to use Phong lighting (only diffuse and specularity atm). Changed default window size to be slightly larger yet fit on 1080p. Added GetModel functions to Camera component. Updated test scene in Engine.cpp Fixed Camera world-space position calculation bug. Renamed Renderer::CameraInfo::ProjectMode to ProjectionMode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nils Petter Skålerud <np_skalerud@hotmail.com> --- Data/Shaders/Mesh/Mesh.frag | 29 ++++++++++++++++++++++++++--- Data/Shaders/Mesh/Mesh.vert | 15 ++++++++------- external/DMath | 2 +- src/Engine/Application.hpp | 2 +- src/Engine/Components/Camera.cpp | 21 ++++++++++++++++++--- src/Engine/Components/Camera.hpp | 4 +++- src/Engine/Engine.cpp | 19 +++++++++++-------- src/Engine/Renderer/OpenGL.cpp | 23 ++++++++++++++++------- src/Engine/Renderer/Renderer.cpp | 4 ++-- src/Engine/Renderer/Renderer.hpp | 5 +++-- 10 files changed, 89 insertions(+), 35 deletions(-) diff --git a/Data/Shaders/Mesh/Mesh.frag b/Data/Shaders/Mesh/Mesh.frag index 72a9dae..9adfd48 100644 --- a/Data/Shaders/Mesh/Mesh.frag +++ b/Data/Shaders/Mesh/Mesh.frag @@ -1,5 +1,11 @@ #version 420 core +layout(std140, binding = 0) uniform CameraData +{ + vec4 wsPosition; + mat4 viewProjection; +} cameraData; + layout(std140, binding = 1) uniform LightData { uint pointLightCount; @@ -13,13 +19,30 @@ in FragData vec2 uv; } fragData; +layout(location = 0) out vec4 frag_color; + void main() { + vec3 pointToCamera = cameraData.wsPosition.xyz - fragData.wsPosition; + vec3 pointToCameraDir = normalize(pointToCamera); + float test = 0.0; for (int i = 0; i < lightData.pointLightCount; i++) { - vec3 pointToLight = normalize(lightData.pointLightPos[i].xyz - fragData.wsPosition); - test += max(dot(pointToLight, fragData.wsNormal), 0); + vec3 pointToLight = lightData.pointLightPos[i].xyz - fragData.wsPosition; + vec3 pointToLightDir = normalize(pointToLight); + + float diff = max(0, dot(pointToLightDir, fragData.wsNormal)); + test += diff; + + vec3 lightToPointDir = -pointToLightDir; + + vec3 reflectDir = reflect(lightToPointDir, fragData.wsNormal); + + float spec = pow(max(dot(pointToCameraDir, reflectDir), 0.0), 50); + + test += spec; + } - gl_FragColor = vec4(test, test, test, test); + frag_color = vec4(test); } diff --git a/Data/Shaders/Mesh/Mesh.vert b/Data/Shaders/Mesh/Mesh.vert index aaee841..af8162a 100644 --- a/Data/Shaders/Mesh/Mesh.vert +++ b/Data/Shaders/Mesh/Mesh.vert @@ -1,11 +1,12 @@ #version 420 core -layout(location = 0) in vec3 position; -layout(location = 1) in vec2 texCoord; -layout(location = 2) in vec3 normal; +layout(location = 0) in vec3 vtxPosition; +layout(location = 1) in vec2 vtxUV; +layout(location = 2) in vec3 vtxNormal; layout(std140, binding = 0) uniform CameraData { + vec4 wsPosition; mat4 viewProjection; } cameraData; @@ -20,9 +21,9 @@ out FragData void main() { - gl_Position = cameraData.viewProjection * model * vec4(position, 1.0); + gl_Position = cameraData.viewProjection * model * vec4(vtxPosition, 1.0); - fragData.wsPosition = vec4(model * vec4(position, 1.0)).xyz; - fragData.wsNormal = vec4(model * vec4(normal, 0.0)).xyz; - fragData.uv = texCoord; + fragData.wsPosition = vec3(model * vec4(vtxPosition, 1.0)); + fragData.wsNormal = mat3(transpose(inverse(model))) * vtxNormal; + fragData.uv = vtxUV; } diff --git a/external/DMath b/external/DMath index a17ca74..62afefe 160000 --- a/external/DMath +++ b/external/DMath @@ -1 +1 @@ -Subproject commit a17ca749764c26300ffaf2d8ffa13da38cc4d630 +Subproject commit 62afefe2fcf6db2471846d3b42800a0ae44f0f8e diff --git a/src/Engine/Application.hpp b/src/Engine/Application.hpp index e4cd30e..fe15414 100644 --- a/src/Engine/Application.hpp +++ b/src/Engine/Application.hpp @@ -10,7 +10,7 @@ namespace Engine { namespace Application { - constexpr Utility::ImgDim defaultWindowSize = { 1280, 720 }; + constexpr Utility::ImgDim defaultWindowSize = { 1800, 900 }; constexpr Utility::ImgDim minimumWindowSize = { 800, 600 }; constexpr float narrowestAspectRatio = minimumWindowSize.GetAspectRatio(); constexpr std::string_view defaultApplicationName = "VulkanProject1"; diff --git a/src/Engine/Components/Camera.cpp b/src/Engine/Components/Camera.cpp index 04d7824..af2e012 100644 --- a/src/Engine/Components/Camera.cpp +++ b/src/Engine/Components/Camera.cpp @@ -1,5 +1,7 @@ #include "Camera.hpp" +#include "../SceneObject.hpp" + #include "DMath/LinearTransform3D.hpp" #include "../Renderer/Renderer.hpp" @@ -30,7 +32,17 @@ namespace Engine forward = (newTarget - positionOffset).GetNormalized(); } - Renderer::CameraInfo Camera::GetCameraInfo() const + Math::Matrix<4, 3, float> Camera::GetModel_Reduced(Space space) const + { + using namespace Math::LinTran3D; + const auto& localModel = Translate_Reduced(positionOffset); + if (space == Space::Local) + return localModel; + else + return Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel); + } + + Renderer::CameraInfo Camera::GetRendererCameraInfo() const { Renderer::CameraInfo cameraInfo; @@ -40,12 +52,15 @@ namespace Engine cameraInfo.zFar = zFar; if (projectionMode == ProjectionMode::Perspective) - cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Perspective; + cameraInfo.projectMode = Renderer::CameraInfo::ProjectionMode::Perspective; else if (projectionMode == ProjectionMode::Orthgraphic) - cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Orthographic; + cameraInfo.projectMode = Renderer::CameraInfo::ProjectionMode::Orthographic; cameraInfo.transform = Math::LinTran3D::LookAt_RH(positionOffset, positionOffset + forward, up); + auto test = GetModel_Reduced(Space::World); + cameraInfo.worldSpacePos = Math::LinTran3D::GetTranslation(test); + return cameraInfo; } } diff --git a/src/Engine/Components/Camera.hpp b/src/Engine/Components/Camera.hpp index 0226c36..de12d6b 100644 --- a/src/Engine/Components/Camera.hpp +++ b/src/Engine/Components/Camera.hpp @@ -1,6 +1,7 @@ #pragma once #include "Components.hpp" +#include "../Enum.hpp" #include "DMath/Vector/Vector.hpp" @@ -42,7 +43,8 @@ namespace Engine void LookAt(const Math::Vector3D& newTarget); - Renderer::CameraInfo GetCameraInfo() const; + [[nodiscard]] Math::Matrix<4, 3, float> GetModel_Reduced(Space space) const; + Renderer::CameraInfo GetRendererCameraInfo() const; }; } } \ No newline at end of file diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp index 5b00171..a89788a 100644 --- a/src/Engine/Engine.cpp +++ b/src/Engine/Engine.cpp @@ -68,13 +68,19 @@ void Engine::Core::Run() Renderer::GetViewport(0).SetSceneRef(&scene1); + + auto& sceneObject1 = scene1.NewSceneObject(); auto& mesh1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); mesh1.SetMesh(Asset::Mesh::Helmet); + auto& meshTest = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); + meshTest.SetMesh(Asset::Mesh::Helmet); + meshTest.positionOffset.x = -3.f; + auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get(); mesh2.SetMesh(Asset::Mesh::Cube); - mesh2.positionOffset.x = 2.5f; + mesh2.positionOffset.x = 2.f; auto& objCamera = scene1.NewSceneObject(); auto& camera = objCamera.AddComponent<Components::Camera>().first.get(); @@ -117,12 +123,12 @@ void Engine::Core::Run() camera.positionOffset += Math::Vector3D::Up() * speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::LeftCtrl)) camera.positionOffset += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime(); - camera.LookAt({ 0, 0, 0 }); + camera.LookAt({ -1.f, 0, 0 }); if (Input::Raw::GetValue(Input::Raw::Button::Up)) - lightObj.transform.localPosition.z += speed * scene1.GetTimeData().GetDeltaTime(); - if (Input::Raw::GetValue(Input::Raw::Button::Down)) lightObj.transform.localPosition.z -= speed * scene1.GetTimeData().GetDeltaTime(); + if (Input::Raw::GetValue(Input::Raw::Button::Down)) + lightObj.transform.localPosition.z += speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::Left)) lightObj.transform.localPosition.x -= speed * scene1.GetTimeData().GetDeltaTime(); if (Input::Raw::GetValue(Input::Raw::Button::Right)) @@ -140,14 +146,11 @@ void Engine::Core::Run() RenderSystem::BuildRenderGraph(scene1, graph); Renderer::Core::PrepareRenderingEarly(graph); - + Renderer::Core::SetCameraInfo(camera.GetRendererCameraInfo()); RenderSystem::BuildRenderGraphTransform(scene1, graphTransform); Renderer::Core::PrepareRenderingLate(graphTransform); - Renderer::Core::SetCameraInfo(camera.GetCameraInfo()); - - Renderer::Core::Draw(); diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp index 065f8be..8648cc9 100644 --- a/src/Engine/Renderer/OpenGL.cpp +++ b/src/Engine/Renderer/OpenGL.cpp @@ -55,13 +55,14 @@ namespace Engine struct Engine::Renderer::OpenGL::CameraDataUBO { + Math::Vector4D wsPosition; Math::Matrix<4, 4, float> viewProjection; }; struct Engine::Renderer::OpenGL::LightDataUBO { uint32_t pointLightCount; - std::array<uint32_t, 3> padding; + std::array<uint32_t, 3> padding1; std::array<Math::Vector4D, 10> pointLightPos; }; @@ -235,7 +236,6 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da // Grab uniforms data.meshModelUniform = glGetUniformLocation(data.meshProgram, "model"); - auto test = glGetUniformBlockIndex(data.meshProgram, "LightData"); glUniformBlockBinding(data.meshProgram, 1, 1); } @@ -340,10 +340,12 @@ void Engine::Renderer::OpenGL::PrepareRenderingEarly(const std::vector<SpriteID> // Update light count const auto& renderGraph = Core::GetRenderGraph(); - uint32_t pointLightCount = renderGraph.pointLights.size(); - glNamedBufferSubData(data.lightDataUBO, 0, sizeof(uint32_t), &pointLightCount); + auto pointLightCount = static_cast<uint32_t>(renderGraph.pointLights.size()); + constexpr GLintptr pointLightCountDataOffset = offsetof(LightDataUBO, LightDataUBO::pointLightCount); + glNamedBufferSubData(data.lightDataUBO, pointLightCountDataOffset, sizeof(pointLightCount), &pointLightCount); } +bool testing = false; void Engine::Renderer::OpenGL::PrepareRenderingLate() { Data& data = GetData(); @@ -356,14 +358,21 @@ void Engine::Renderer::OpenGL::PrepareRenderingLate() for (size_t i = 0; i < elements; i++) posData[i] = renderGraphTransform.pointLights[i].AsVec4(); size_t byteLength = sizeof(Math::Vector4D) * elements; - - glNamedBufferSubData(data.lightDataUBO, sizeof(uint32_t) * 4, byteLength, posData.data()); + constexpr GLintptr pointLightPosDataOffset = offsetof(LightDataUBO, LightDataUBO::pointLightPos); + glNamedBufferSubData(data.lightDataUBO, pointLightPosDataOffset, byteLength, posData.data()); auto& viewport = Renderer::GetViewport(0); + // Update camera UBO auto& cameraInfo = Renderer::Core::GetCameraInfo(); + const Math::Vector4D& cameraWSPosition = cameraInfo.worldSpacePos.AsVec4(); + constexpr GLintptr cameraWSPositionDataOffset = offsetof(CameraDataUBO, CameraDataUBO::wsPosition); + glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO); + glBufferSubData(GL_UNIFORM_BUFFER, cameraWSPositionDataOffset, sizeof(cameraWSPosition), cameraWSPosition.Data()); + auto viewMatrix = cameraInfo.GetModel(viewport.GetDimensions().GetAspectRatio()); - glNamedBufferSubData(data.cameraDataUBO, 0, sizeof(CameraDataUBO::viewProjection), viewMatrix.data.data()); + constexpr GLintptr cameraViewProjectionDataOffset = offsetof(CameraDataUBO, CameraDataUBO::viewProjection); + glBufferSubData(GL_UNIFORM_BUFFER, cameraViewProjectionDataOffset, sizeof(viewMatrix), viewMatrix.Data()); } void Engine::Renderer::OpenGL::Draw() diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp index 97aef6c..d2fc6ef 100644 --- a/src/Engine/Renderer/Renderer.cpp +++ b/src/Engine/Renderer/Renderer.cpp @@ -254,7 +254,7 @@ void Engine::Renderer::Core::UpdateAssetReferences(Data& data, const RenderGraph Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const { using namespace Math::LinTran3D; - if (projectMode == ProjectMode::Perspective) + if (projectMode == ProjectionMode::Perspective) { switch (GetActiveAPI()) { @@ -267,7 +267,7 @@ Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const return {}; } } - else if (projectMode == ProjectMode::Orthographic) + else if (projectMode == ProjectionMode::Orthographic) { const float& right = orthoWidth / 2; const float& left = -right; diff --git a/src/Engine/Renderer/Renderer.hpp b/src/Engine/Renderer/Renderer.hpp index ad5a549..22d9a53 100644 --- a/src/Engine/Renderer/Renderer.hpp +++ b/src/Engine/Renderer/Renderer.hpp @@ -93,14 +93,15 @@ namespace Engine struct Renderer::CameraInfo { - enum class ProjectMode + enum class ProjectionMode { Perspective, Orthographic }; Math::Matrix4x4 transform; - ProjectMode projectMode; + Math::Vector3D worldSpacePos; + ProjectionMode projectMode; float fovY; float zNear; float zFar; -- GitLab