From a9f2911e416057fb33aef595f1a1cf3925fafca2 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 23 May 2014 22:42:11 +0200 Subject: [PATCH] Shadows working, and looking totaly not shit. Improved location of the shadowmap to always be infront of the camera. --- assets | 2 +- src/Camera.cpp | 8 +-- src/GameWorld.cpp | 91 +++++++++++++++++++++++++++++---- src/Renderer.cpp | 65 +++++++++++++++++------ src/Renderer.h | 4 ++ src/Shaders/FinalPass.frag.glsl | 2 +- src/Shaders/Fragment.glsl | 20 ++++++-- 7 files changed, 158 insertions(+), 34 deletions(-) diff --git a/assets b/assets index 21182ef..11db88f 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 21182efb938beeb1daca5d24f9957d394bfb8683 +Subproject commit 11db88fb3da152311ed70c02347008c16ee0f3c6 diff --git a/src/Camera.cpp b/src/Camera.cpp index 1256e64..55a22fb 100755 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -16,10 +16,10 @@ Camera::Camera(float yFOV, float aspectRatio, float nearClip, float farClip) UpdateViewMatrix(); } -//glm::vec3 Camera::Forward() -//{ -// return glm::rotate(glm::vec3(0.f, 0.f, -1.f), -m_Yaw, glm::vec3(0.f, 1.f, 0.f)); -//} +glm::vec3 Camera::Forward() +{ + return m_Orientation * glm::vec3(0, 0, -1); +} // //glm::vec3 Camera::Right() //{ diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index de85a0a..9d77dac 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -17,14 +17,14 @@ void GameWorld::Initialize() auto ground = CreateEntity(); auto transform = AddComponent(ground, "Transform"); transform->Position = glm::vec3(0, -5, 0); - transform->Scale = glm::vec3(800.0f, 10.0f, 800.0f); + transform->Scale = glm::vec3(1600.0f, 10.0f, 1600.0f); transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); auto model = AddComponent(ground, "Model"); model->ModelFile = "Models/Placeholders/PhysicsTest/Cube.obj"; auto box = AddComponent(ground, "Box"); - box->Width = 400; + box->Width = 800; box->Height = 5; - box->Depth = 400; + box->Depth = 800; auto physics = AddComponent(ground, "Physics"); physics->Mass = 10; @@ -33,18 +33,18 @@ void GameWorld::Initialize() CommitEntity(ground); } - for(int i = 15; i < 200; i++) + for(int i = 0; i < 50; i++) { auto Light = CreateEntity(); auto transform = AddComponent(Light, "Transform"); - transform->Position = glm::vec3((5+(i/2.f))*cos(i/5.0f), 3.f, (5+(i/2.f))*sin(i/5.0f)); + transform->Position = glm::vec3((5+(i*2.f))*cos(i*2.f), 3.f, (5+(i*2.f))*sin(i*2.f)); auto light = AddComponent(Light, "PointLight"); light->Specular = glm::vec3(0.5f, 0.5f, 0.5f); light->Diffuse = glm::vec3(0.5f, 0.5f, 0.5f); light->Radius = 15.f; light->specularExponent = 100.f; - auto model = AddComponent(Light, "Model"); - model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; + //auto model = AddComponent(Light, "Model"); + //model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; } { @@ -239,11 +239,11 @@ void GameWorld::Initialize() } */ - for(int i = 0; i < 10; i++) + for(int i = 0; i < 20; i++) { auto cube = CreateEntity(); auto transform = AddComponent(cube, "Transform"); - transform->Position = glm::vec3(20, 10 + i*2, 0); + transform->Position = glm::vec3(10, 2, -10+i); //transform->Scale = glm::vec3(1); transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); auto model = AddComponent(cube, "Model"); @@ -257,6 +257,79 @@ void GameWorld::Initialize() box->Depth = 0.5f; CommitEntity(cube); } + for(int i = 0; i < 20; i++) + { + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(-10, 2, -10+i); + //transform->Scale = glm::vec3(1); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(cube, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(cube, "Physics"); + physics->Mass = 100; + auto box = AddComponent(cube, "Box"); + box->Width = 0.5f; + box->Height = 0.5f; + box->Depth = 0.5f; + CommitEntity(cube); + } + + for(int i = 0; i < 20; i++) + { + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(-10+i, 2, 10); + //transform->Scale = glm::vec3(1); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(cube, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(cube, "Physics"); + physics->Mass = 100; + auto box = AddComponent(cube, "Box"); + box->Width = 0.5f; + box->Height = 0.5f; + box->Depth = 0.5f; + CommitEntity(cube); + } + + for(int i = 0; i < 20; i++) + { + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(-10+i, 2, -10); + //transform->Scale = glm::vec3(1); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(cube, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(cube, "Physics"); + physics->Mass = 100; + auto box = AddComponent(cube, "Box"); + box->Width = 0.5f; + box->Height = 0.5f; + box->Depth = 0.5f; + CommitEntity(cube); + } + + for(int i = 0; i < 10; i++) + { + auto sphere = CreateEntity(); + auto transform = AddComponent(sphere, "Transform"); + transform->Position = glm::vec3(5, 10 + i*2, 5); + //transform->Scale = glm::vec3(1); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(sphere, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Sphere.obj"; + + auto physics = AddComponent(sphere, "Physics"); + physics->Mass = 100; + auto ball = AddComponent(sphere, "Sphere"); + ball->Radius = 0.5; + CommitEntity(sphere); + } /*{ auto entity = CreateEntity(); diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 000c04a..de2d8c3 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -17,10 +17,13 @@ Renderer::Renderer() CAtt = 1.0f; LAtt = 0.0f; QAtt = 3.0f; - m_ShadowMapRes = 2048*6; - m_SunPosition = glm::vec3(3.f, 5.f, 3.f); + m_ShadowMapRes = 2048*8; + m_SunPosition = glm::vec3(0.f, 1.0f, 0.5f); m_SunTarget = glm::vec3(0, 0, 0); - m_SunProjection = glm::ortho(200.f, -200.f, 200.f, -200.f, -100.f, 100.f); + m_SunProjection_height = glm::vec2(-40.f, 40.f); + m_SunProjection_width = glm::vec2(-40.f, 40.f); + m_SunProjection_length = glm::vec2(-50.f, 50.f); + m_SunProjection = glm::ortho(m_SunProjection_width.x, m_SunProjection_width.y, m_SunProjection_height.x, m_SunProjection_height.y, m_SunProjection_length.x, m_SunProjection_length.y); /* Lights = 0;*/ } @@ -152,17 +155,44 @@ void Renderer::Draw(double dt) m_QuadView = true; } - if(glfwGetKey(m_Window, GLFW_KEY_KP_1)) + //if(glfwGetKey(m_Window, GLFW_KEY_KP_1)) + //{ + // Gamma -= 0.3f * dt; + // LOG_INFO("Gamma_UP: %f", Gamma); + //} + //if(glfwGetKey(m_Window, GLFW_KEY_KP_4)) + //{ + // Gamma += 0.3f * dt; + // LOG_INFO("Gamma_DOWN: %f", Gamma); + //} + + if(glfwGetKey(m_Window, GLFW_KEY_KP_7)) { - Gamma -= 0.3f * dt; - LOG_INFO("Gamma_UP: %f", Gamma); + m_SunProjection_height.x += 10.f * dt; + LOG_INFO("Heightx+: %f", m_SunProjection_height); + m_SunProjection = glm::ortho(m_SunProjection_width.x, m_SunProjection_width.y, m_SunProjection_height.x, m_SunProjection_height.y, m_SunProjection_length.x, m_SunProjection_length.y); } - if(glfwGetKey(m_Window, GLFW_KEY_KP_4)) + else if(glfwGetKey(m_Window, GLFW_KEY_KP_4)) { - Gamma += 0.3f * dt; - LOG_INFO("Gamma_DOWN: %f", Gamma); + m_SunProjection_height.x -= 10.f * dt; + LOG_INFO("Heightx-: %f", m_SunProjection_height); + m_SunProjection = glm::ortho(m_SunProjection_width.x, m_SunProjection_width.y, m_SunProjection_height.x, m_SunProjection_height.y, m_SunProjection_length.x, m_SunProjection_length.y); } + if(glfwGetKey(m_Window, GLFW_KEY_KP_8)) + { + m_SunProjection_height.y += 10.f * dt; + LOG_INFO("Heightx+: %f", m_SunProjection_height); + m_SunProjection = glm::ortho(m_SunProjection_width.x, m_SunProjection_width.y, m_SunProjection_height.x, m_SunProjection_height.y, m_SunProjection_length.x, m_SunProjection_length.y); + } + else if(glfwGetKey(m_Window, GLFW_KEY_KP_5)) + { + m_SunProjection_height.y -= 10.f * dt; + LOG_INFO("Heightx-: %f", m_SunProjection_height); + m_SunProjection = glm::ortho(m_SunProjection_width.x, m_SunProjection_width.y, m_SunProjection_height.x, m_SunProjection_height.y, m_SunProjection_length.x, m_SunProjection_length.y); + } + + if(glfwGetKey(m_Window, GLFW_KEY_1)) { if(glfwGetKey(m_Window, GLFW_KEY_KP_ADD)) @@ -235,8 +265,8 @@ void Renderer::CreateShadowMap(int resolution) glGenTextures(1, &m_ShadowDepthTexture); glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); @@ -256,7 +286,7 @@ void Renderer::DrawShadowMap() { glEnable(GL_DEPTH_TEST);//Tests where objects are and display them correctly glEnable(GL_CULL_FACE); //removes triangles on the wrong side of the object - glCullFace(GL_BACK); //Make it so that only the back faces are rendered + glCullFace(GL_FRONT); //Make it so that only the back faces are rendered //Binds the FBO and sets the veiwport, witch in effect is how large the shadowmap is and what resolution it has. glBindFramebuffer(GL_FRAMEBUFFER, m_ShadowFrameBuffer); @@ -266,7 +296,7 @@ void Renderer::DrawShadowMap() //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Creates the "camera" for the shadowmap from the direction of the sun. - glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)); + glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)) * glm::translate((-m_Camera->Position() + (glm::vec3(40.0) * -m_Camera->Forward())) * glm::vec3(1,0,1)); glm::mat4 depthCamera = m_SunProjection * depthViewMatrix; glm::mat4 MVP; @@ -292,7 +322,6 @@ void Renderer::DrawShadowMap() glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1); } } - } void Renderer::DrawDebugShadowMap() @@ -698,11 +727,15 @@ void Renderer::DrawFBOScene() 0.5, 0.5, 0.5, 1.0 ); - glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)); + glm::mat4 depthViewMatrix = glm::lookAt(m_SunPosition, m_SunTarget, glm::vec3(0, 1, 0)) * glm::translate((-m_Camera->Position() + (glm::vec3(40.0) * -m_Camera->Forward())) * glm::vec3(1,0,1)); glm::mat4 depthCamera = m_SunProjection * depthViewMatrix; glm::mat4 depthCameraMatrix = biasMatrix * depthCamera; glm::mat4 depthMVP; + glm::vec3 sunDirection = m_SunTarget - m_SunPosition; + glm::vec3 sunDirection_cameraview = glm::vec3(m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * glm::vec4(sunDirection, 1.0)); + //Proj * view * vector + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_ShadowDepthTexture); @@ -722,6 +755,8 @@ void Renderer::DrawFBOScene() glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(m_FirstPassProgram.GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + glUniform3fv(glGetUniformLocation(m_SecondPassProgram.GetHandle(), "SunDirection_cameraspace"), 1, glm::value_ptr(sunDirection_cameraview)); + glBindVertexArray(model->VAO); for (auto texGroup : model->TextureGroups) { diff --git a/src/Renderer.h b/src/Renderer.h index 0c784ba..d1baa54 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -94,6 +94,10 @@ private: glm::vec3 m_SunPosition; glm::vec3 m_SunTarget; glm::mat4 m_SunProjection; + glm::vec2 m_SunProjection_width; + glm::vec2 m_SunProjection_height; + glm::vec2 m_SunProjection_length; + GLuint m_DebugAABB; GLuint m_ShadowFrameBuffer; diff --git a/src/Shaders/FinalPass.frag.glsl b/src/Shaders/FinalPass.frag.glsl index df251d4..b4dcc13 100644 --- a/src/Shaders/FinalPass.frag.glsl +++ b/src/Shaders/FinalPass.frag.glsl @@ -21,7 +21,7 @@ void main() vec4 LightingTexel = texture(LightingTexture, Input.TextureCoord); vec4 ShadowTexel = texture(ShadowTexture, Input.TextureCoord); - //FragmentColor = LightingTexel; + //FragmentColor = DiffuseTexel; FragmentColor = DiffuseTexel * (vec4(La, 0.0) + vec4(LightingTexel.rgb, 0.0)) + vec4(LightingTexel.a, LightingTexel.a, LightingTexel.a, 0.0); //FragmentColor = vec4(pow(_FragmentColor.rgb, vec3(1.0 / Gamma)), _FragmentColor.a); diff --git a/src/Shaders/Fragment.glsl b/src/Shaders/Fragment.glsl index 3c9d8a7..725bb17 100755 --- a/src/Shaders/Fragment.glsl +++ b/src/Shaders/Fragment.glsl @@ -5,6 +5,8 @@ layout (binding=1) uniform sampler2D ShadowTexture; layout (binding=2) uniform sampler2D NormalMapTexture; layout (binding=3) uniform sampler2D SpecularMapTexture; +uniform vec3 SunDirection_cameraspace; +uniform mat4 V; in VertexData { @@ -23,10 +25,20 @@ out vec4 frag_Specular; float Shadow(vec4 ShadowCoord) { - //float cosTheta = clamp(dot(Input.Normal, 1.0), 0.0, 1.0); - float bias = 0.0005; // cosTheta is dot( n,l ), clamped between 0 and 1 - bias = clamp(bias, 0.0, 0.01); - if( texture(ShadowTexture, Input.ShadowCoord.xy).z < ShadowCoord.z - bias) + if (Input.ShadowCoord.x < 0.0 || Input.ShadowCoord.x > 1.0 || Input.ShadowCoord.y < 0.0 || Input.ShadowCoord.y > 1.0) + return 0.9; + + //Fixed bias + //float bias = 0.00005; + + //Variable bias + vec3 n = normalize(Input.Normal); + vec3 l = normalize(SunDirection_cameraspace); + float cosTheta = clamp(dot(n, l), 0.0, 1.0); + float bias = tan(acos(cosTheta)); + bias = clamp(bias, 0.0, 0.00005); + + if( texture(ShadowTexture, Input.ShadowCoord.xy).z < ShadowCoord.z + bias) { return 0.6; }