From f27a35422609b1da7a9d572af353015261db2b96 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Thu, 15 Mar 2018 11:54:00 +0100 Subject: [PATCH] Simple shadow mapping works - Yay --- data/shaders/fs_default.glsl | 6 +- data/shaders/fs_shadowmap.frag | 5 +- data/shaders/vs_default.glsl | 2 +- data/shaders/vs_shadowmap.vert | 6 +- src/modules/RenderModule.cc | 110 +++++++++++++++++++++------------ src/modules/RenderModule.h | 11 ++-- src/modules/RenderUtils.cc | 10 +-- 7 files changed, 87 insertions(+), 63 deletions(-) diff --git a/data/shaders/fs_default.glsl b/data/shaders/fs_default.glsl index 6e2ba9e..bdde627 100644 --- a/data/shaders/fs_default.glsl +++ b/data/shaders/fs_default.glsl @@ -23,9 +23,9 @@ float ShadowCalculation(vec4 frag_pos_light_space) { float current_depth = projected_coordinates.z; // return current_depth; - return closest_depth; -// float bias = 0.005; -// return current_depth - bias > closest_depth ? 1.0 : 0.0; +// return closest_depth; + float bias = 0.005; + return current_depth - bias > closest_depth ? 1.0 : 0.0; // return current_depth; } diff --git a/data/shaders/fs_shadowmap.frag b/data/shaders/fs_shadowmap.frag index 37fe227..c7eea38 100644 --- a/data/shaders/fs_shadowmap.frag +++ b/data/shaders/fs_shadowmap.frag @@ -1,13 +1,10 @@ #version 150 core - -smooth in vec4 ioFragColor; +in vec4 ioFragColor; in vec3 ioFragPosition; out vec4 outColor; void main() { - gl_FragDepth = gl_FragCoord.z; - outColor = ioFragColor; } diff --git a/data/shaders/vs_default.glsl b/data/shaders/vs_default.glsl index 5bb1b01..ad54b26 100644 --- a/data/shaders/vs_default.glsl +++ b/data/shaders/vs_default.glsl @@ -22,7 +22,7 @@ out vec4 ioFragPosLightSpace; void main() { ioFragPosition = (uModelMatrix * inCoord).xyz; - ioFragNormal = uNormalMatrix * inNormal; + ioFragNormal = transpose(inverse(mat3(uModelMatrix))) * inNormal; ioFragTexCoords = inUV; ioFragColor = inColor; ioFragPosLightSpace = uLightSpaceMatrix * vec4(ioFragPosition, 1.0); diff --git a/data/shaders/vs_shadowmap.vert b/data/shaders/vs_shadowmap.vert index ccc0f6d..e068f72 100644 --- a/data/shaders/vs_shadowmap.vert +++ b/data/shaders/vs_shadowmap.vert @@ -1,12 +1,16 @@ #version 150 core in vec4 inCoord; +in vec3 inNormal; +in vec2 inUV; in vec4 inColor; +uniform mat4 uViewMatrix; +uniform mat4 uProjectionMatrix; uniform mat4 uModelMatrix; uniform mat4 uLightSpaceMatrix; -smooth out vec4 ioFragColor; +out vec4 ioFragColor; void main() { gl_Position = uLightSpaceMatrix * uModelMatrix * inCoord; diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index ff0933f..d20ba71 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -1,4 +1,5 @@ #include "RuntimeModule.h" +#include "Timer.h" #include "Globals.h" #include "RenderModule.h" #include @@ -89,15 +90,12 @@ static void module_serialize ( SerializeVec3(*serializer, "protot.RenderModule.Camera.mUp", gRenderer->mCamera.mUp); SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear); SerializeFloat(*serializer, "protot.RenderModule.Camera.mFar", gRenderer->mCamera.mFar); + + SerializeVec3(*serializer, "protot.RenderModule.mLight.mPosition", gRenderer->mLight.mPosition); SerializeVec3(*serializer, "protot.RenderModule.mLight.mDirection", gRenderer->mLight.mDirection); + SerializeFloat(*serializer, "protot.RenderModule.mLight.mBBoxSize", gRenderer->mLight.mBBoxSize); SerializeFloat(*serializer, "protot.RenderModule.mLight.mNear", gRenderer->mLight.mNear); SerializeFloat(*serializer, "protot.RenderModule.mLight.mFar", gRenderer->mLight.mFar); - -// SerializeBool (*serializer, "protot.RenderModule.draw_floor", gRenderer->drawFloor); -// SerializeBool (*serializer, "protot.RenderModule.draw_skybox", gRenderer->drawSkybox); -// SerializeBool (*serializer, "protot.RenderModule.debug_enabled", gRenderer->drawDebug); -// SerializeVec3 (*serializer, "protot.RenderModule.camera.eye", camera->eye); -// SerializeVec3 (*serializer, "protot.RenderModule.camera.poi", camera->poi); } static void module_finalize(struct module_state *state) { @@ -178,17 +176,39 @@ void Light::Initialize() { void Light::UpdateMatrices() { mCamera.mIsOrthographic = true; - mCamera.mWidth = 20.0f; - mCamera.mHeight = 20.0f; - mCamera.mNear = mNear; - mCamera.mFar = mFar; - mCamera.mEye = Vector3f (10.0f, 10.0f, 10.0f); - mCamera.mPoi = Vector3f (0.0f, 0.0f, 0.0f); + mCamera.mProjectionMatrix = Ortho (-mBBoxSize * 0.5f, mBBoxSize * 0.5f, -mBBoxSize * 0.5f, mBBoxSize * 0.5f, mNear, mFar); + mCamera.mViewMatrix = LookAt (mCamera.mEye, mCamera.mPoi, mCamera.mUp); - mCamera.UpdateMatrices(); + mLightSpaceMatrix = mCamera.mViewMatrix * mCamera.mProjectionMatrix; +} - mLightSpaceMatrix = mCamera.mProjectionMatrix * mCamera.mViewMatrix; +void Light::DrawGui() { + ImGui::SliderFloat3("Position", mPosition.data(), -10.0f, 10.0f); + ImGui::SliderFloat3("Direction", mDirection.data(), -1.0f, 1.0f); + ImGui::SliderFloat("Volume Size", &mBBoxSize, 1.0f, 50.0f); + ImGui::SliderFloat("Near", &mNear, -10.0f, 50.0f); + ImGui::SliderFloat("Far", &mFar, -10.0f, 50.0f); + + mCamera.mEye = mPosition; + mCamera.mPoi = mPosition - mDirection; + mCamera.mUp = Vector3f (0.0f, 1.0f, 0.0f); + + ImVec2 content_avail = ImGui::GetContentRegionAvail(); + + ImGui::Checkbox("Draw Light Depth", &sRendererSettings.DrawLightDepth); + void* texture; + if (sRendererSettings.DrawLightDepth) { + texture = (void*) mShadowMapTarget.mLinearizedDepthTexture; + } else { + texture = (void*) mShadowMapTarget.mColorTexture; + } + + ImGui::Image(texture, + ImVec2(content_avail.x, content_avail.x), + ImVec2(0.0f, 1.0f), + ImVec2(1.0f, 0.0f) + ); } // @@ -248,10 +268,10 @@ void Renderer::Initialize(int width, int height) { // Plane Mesh gXZPlaneMesh.Initialize(gVertexArray, 4); VertexArray::VertexData plane_mesh_vertex_data[] = { - {-10.0f, 0.0f, -10.0f, 1.0f, 0.0f, 1.0f, 0.0f, -10.0f, -10.0f, 255, 255, 255, 255}, - {-10.0f, 0.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f, -10.0f, 10.0f, 255, 255, 255, 255}, - { 10.0f, 0.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 10.0f, 255, 255, 255, 255}, - { 10.0f, 0.0f, -10.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f, -10.0f, 255, 255, 255, 255} + {-10.0f, 0.0f, -10.0f, 1.0f, 0.0f, 1.0f, 0.0f, -5.0f, -5.0f, 255, 255, 255, 255}, + {-10.0f, 0.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f, -5.0f, 5.0f, 255, 255, 255, 255}, + { 10.0f, 0.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f, 5.0f, 5.0f, 255, 255, 255, 255}, + { 10.0f, 0.0f, -10.0f, 1.0f, 0.0f, 1.0f, 0.0f, 5.0f, -5.0f, 255, 255, 255, 255} }; gXZPlaneMesh.SetData(plane_mesh_vertex_data, 4); GLuint xz_plane_index_data[] = { @@ -390,6 +410,7 @@ void Renderer::RenderGl() { glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize); mLight.UpdateMatrices(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); glUseProgram(mLight.mShadowMapProgram.mProgramId); if (mLight.mShadowMapProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); @@ -415,8 +436,6 @@ void Renderer::RenderGl() { // enable the render target mRenderTarget.Bind(); - GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, DrawBuffers); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { gLog ("Cannot render: frame buffer invalid!"); @@ -457,7 +476,6 @@ void Renderer::RenderGl() { if (mDefaultProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); } - RenderScene(mDefaultProgram, mCamera); @@ -495,9 +513,37 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { program.SetInt("uAlbedoTexture", 1); gVertexArray.Bind(); - program.SetMat44("uModelMatrix", TranslateMat44(3.0, 2.0, 0.0)); + + program.SetMat44("uModelMatrix", + RotateMat44(sin(0.3 * gTimer->mCurrentTime) * 180.0f, + 0.0f, 1.0f, 0.0f) + * TranslateMat44(3.0, 1.0 + sin(2.0f * gTimer->mCurrentTime), 0.0)) ; + program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); gUnitCubeMesh.Draw(GL_TRIANGLES); + program.SetMat44("uModelMatrix", + RotateMat44(60.0f, 0.0f, 1.0f, 0.0f) + * TranslateMat44(-4.0f, 1.0f, 4.0f) + * ScaleMat44(0.5f, 0.5f, 0.5f)); + program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); + gUnitCubeMesh.Draw(GL_TRIANGLES); + + program.SetMat44("uModelMatrix", + RotateMat44(60.0f, 0.0f, 1.0f, 0.0f) + * TranslateMat44(4.0f, 1.0f, 5.0f) + * ScaleMat44(0.8f, 0.8f, 0.8f)); + program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); + gUnitCubeMesh.Draw(GL_TRIANGLES); + + program.SetMat44("uModelMatrix", + RotateMat44(200.0f, 0.0f, 1.0f, 0.0f) + * TranslateMat44(-2.0f, 1.0f, -8.0f) + * ScaleMat44(0.5f, 0.5f, 0.5f)); + + program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); + gUnitCubeMesh.Draw(GL_TRIANGLES); + + program.SetMat44("uModelMatrix", Matrix44f::Identity()); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); gXZPlaneMesh.Draw(GL_TRIANGLES); @@ -529,25 +575,7 @@ void Renderer::RenderGui() { ImGui::EndDock(); if (ImGui::BeginDock("Light Settings")) { - mLight.mCamera.DrawGui(); - ImGui::SliderFloat3("Direction", mLight.mDirection.data(), -10.0f, 10.0f); - ImVec2 content_avail = ImGui::GetContentRegionAvail(); - - ImGui::SliderFloat("Light Near", &mLight.mNear, -10.0f, 50.0f); - ImGui::SliderFloat("Light Far", &mLight.mFar, -10.0f, 50.0f); - ImGui::Checkbox("Draw Light Depth", &mSettings->DrawLightDepth); - void* texture; - if (mSettings->DrawLightDepth) { - texture = (void*) mLight.mShadowMapTarget.mLinearizedDepthTexture; - } else { - texture = (void*) mLight.mShadowMapTarget.mColorTexture; - } - - ImGui::Image(texture, - ImVec2(content_avail.x, content_avail.x), - ImVec2(0.0f, 1.0f), - ImVec2(1.0f, 0.0f) - ); + mLight.DrawGui(); } ImGui::EndDock(); diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index d7b71d2..ef4ceb6 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -33,19 +33,20 @@ struct Light { Matrix44f mLightSpaceMatrix; Light() : - mPosition (Vector3f(0.f, 10.f, 10.f)), - mDirection (Vector3f(-1.f, -1.f, -1.f)), + mPosition (Vector3f(0.f, 3, 0.0f)), + mDirection (Vector3f(1.f, 1.f, 1.f)), mShadowMapBias (0.004f), mShadowMapSize (1024), - mNear (0.01f), - mFar (6.f), - mBBoxSize (5.f), + mNear (-10.0f), + mFar (15.f), + mBBoxSize (35.f), mLightSpaceMatrix(Matrix44f::Identity()) { } void Initialize(); void UpdateMatrices(); + void DrawGui(); }; struct RendererSettings; diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 08d9bf3..84d5abe 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -29,9 +29,6 @@ void Camera::UpdateMatrices() { float width = mWidth * 0.5f * (mFar - mNear * 0.5f) * 0.001f; float height = width * mHeight / mWidth; -// width = mWidth; -// height = mHeight; - mProjectionMatrix = Ortho(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, mNear, mFar); } else { mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar); @@ -286,8 +283,8 @@ void RenderTarget::Initialize(int width, int height, int flags) { void RenderTarget::Bind() { assert(glIsFramebuffer(mFrameBufferId)); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); - GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, DrawBuffers); + GLenum shadow_map_draw_buffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, shadow_map_draw_buffers); } void RenderTarget::Cleanup() { @@ -412,14 +409,11 @@ void RenderTarget::RenderToLinearizedDepth(const float& near, const float& far, glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_DEPTH_TEST); - Matrix44f model_view_projection = Matrix44f::Identity(); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mDepthTexture); // render depth texture glUseProgram(mLinearizeDepthProgram.mProgramId); - mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection); mLinearizeDepthProgram.SetFloat("uNear", near); mLinearizeDepthProgram.SetFloat("uFar", far); mLinearizeDepthProgram.SetFloat("uIsOrthographic", is_orthographic ? 1.0f : 0.0f);