Simple shadow mapping works - Yay

simple_math_single_header
Martin Felis 2018-03-15 11:54:00 +01:00
parent cb13324846
commit f27a354226
7 changed files with 87 additions and 63 deletions

View File

@ -23,9 +23,9 @@ float ShadowCalculation(vec4 frag_pos_light_space) {
float current_depth = projected_coordinates.z; float current_depth = projected_coordinates.z;
// return current_depth; // return current_depth;
return closest_depth; // return closest_depth;
// float bias = 0.005; float bias = 0.005;
// return current_depth - bias > closest_depth ? 1.0 : 0.0; return current_depth - bias > closest_depth ? 1.0 : 0.0;
// return current_depth; // return current_depth;
} }

View File

@ -1,13 +1,10 @@
#version 150 core #version 150 core
in vec4 ioFragColor;
smooth in vec4 ioFragColor;
in vec3 ioFragPosition; in vec3 ioFragPosition;
out vec4 outColor; out vec4 outColor;
void main() { void main() {
gl_FragDepth = gl_FragCoord.z;
outColor = ioFragColor; outColor = ioFragColor;
} }

View File

@ -22,7 +22,7 @@ out vec4 ioFragPosLightSpace;
void main() { void main() {
ioFragPosition = (uModelMatrix * inCoord).xyz; ioFragPosition = (uModelMatrix * inCoord).xyz;
ioFragNormal = uNormalMatrix * inNormal; ioFragNormal = transpose(inverse(mat3(uModelMatrix))) * inNormal;
ioFragTexCoords = inUV; ioFragTexCoords = inUV;
ioFragColor = inColor; ioFragColor = inColor;
ioFragPosLightSpace = uLightSpaceMatrix * vec4(ioFragPosition, 1.0); ioFragPosLightSpace = uLightSpaceMatrix * vec4(ioFragPosition, 1.0);

View File

@ -1,12 +1,16 @@
#version 150 core #version 150 core
in vec4 inCoord; in vec4 inCoord;
in vec3 inNormal;
in vec2 inUV;
in vec4 inColor; in vec4 inColor;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelMatrix; uniform mat4 uModelMatrix;
uniform mat4 uLightSpaceMatrix; uniform mat4 uLightSpaceMatrix;
smooth out vec4 ioFragColor; out vec4 ioFragColor;
void main() { void main() {
gl_Position = uLightSpaceMatrix * uModelMatrix * inCoord; gl_Position = uLightSpaceMatrix * uModelMatrix * inCoord;

View File

@ -1,4 +1,5 @@
#include "RuntimeModule.h" #include "RuntimeModule.h"
#include "Timer.h"
#include "Globals.h" #include "Globals.h"
#include "RenderModule.h" #include "RenderModule.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -89,15 +90,12 @@ static void module_serialize (
SerializeVec3(*serializer, "protot.RenderModule.Camera.mUp", gRenderer->mCamera.mUp); SerializeVec3(*serializer, "protot.RenderModule.Camera.mUp", gRenderer->mCamera.mUp);
SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear); SerializeFloat(*serializer, "protot.RenderModule.Camera.mNear", gRenderer->mCamera.mNear);
SerializeFloat(*serializer, "protot.RenderModule.Camera.mFar", gRenderer->mCamera.mFar); 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); 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.mNear", gRenderer->mLight.mNear);
SerializeFloat(*serializer, "protot.RenderModule.mLight.mFar", gRenderer->mLight.mFar); 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) { static void module_finalize(struct module_state *state) {
@ -178,17 +176,39 @@ void Light::Initialize() {
void Light::UpdateMatrices() { void Light::UpdateMatrices() {
mCamera.mIsOrthographic = true; 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.mProjectionMatrix = Ortho (-mBBoxSize * 0.5f, mBBoxSize * 0.5f, -mBBoxSize * 0.5f, mBBoxSize * 0.5f, mNear, mFar);
mCamera.mPoi = Vector3f (0.0f, 0.0f, 0.0f); 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 // Plane Mesh
gXZPlaneMesh.Initialize(gVertexArray, 4); gXZPlaneMesh.Initialize(gVertexArray, 4);
VertexArray::VertexData plane_mesh_vertex_data[] = { 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, -5.0f, -5.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, 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, 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}
}; };
gXZPlaneMesh.SetData(plane_mesh_vertex_data, 4); gXZPlaneMesh.SetData(plane_mesh_vertex_data, 4);
GLuint xz_plane_index_data[] = { GLuint xz_plane_index_data[] = {
@ -390,6 +410,7 @@ void Renderer::RenderGl() {
glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize); glViewport(0, 0, mLight.mShadowMapSize, mLight.mShadowMapSize);
mLight.UpdateMatrices(); mLight.UpdateMatrices();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(mLight.mShadowMapProgram.mProgramId); glUseProgram(mLight.mShadowMapProgram.mProgramId);
if (mLight.mShadowMapProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { if (mLight.mShadowMapProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) {
gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix");
@ -415,8 +436,6 @@ void Renderer::RenderGl() {
// enable the render target // enable the render target
mRenderTarget.Bind(); mRenderTarget.Bind();
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
gLog ("Cannot render: frame buffer invalid!"); gLog ("Cannot render: frame buffer invalid!");
@ -457,7 +476,6 @@ void Renderer::RenderGl() {
if (mDefaultProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { if (mDefaultProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) {
gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix");
} }
RenderScene(mDefaultProgram, mCamera); RenderScene(mDefaultProgram, mCamera);
@ -495,9 +513,37 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
program.SetInt("uAlbedoTexture", 1); program.SetInt("uAlbedoTexture", 1);
gVertexArray.Bind(); 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); 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.SetMat44("uModelMatrix", Matrix44f::Identity());
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
gXZPlaneMesh.Draw(GL_TRIANGLES); gXZPlaneMesh.Draw(GL_TRIANGLES);
@ -529,25 +575,7 @@ void Renderer::RenderGui() {
ImGui::EndDock(); ImGui::EndDock();
if (ImGui::BeginDock("Light Settings")) { if (ImGui::BeginDock("Light Settings")) {
mLight.mCamera.DrawGui(); mLight.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)
);
} }
ImGui::EndDock(); ImGui::EndDock();

View File

@ -33,19 +33,20 @@ struct Light {
Matrix44f mLightSpaceMatrix; Matrix44f mLightSpaceMatrix;
Light() : Light() :
mPosition (Vector3f(0.f, 10.f, 10.f)), mPosition (Vector3f(0.f, 3, 0.0f)),
mDirection (Vector3f(-1.f, -1.f, -1.f)), mDirection (Vector3f(1.f, 1.f, 1.f)),
mShadowMapBias (0.004f), mShadowMapBias (0.004f),
mShadowMapSize (1024), mShadowMapSize (1024),
mNear (0.01f), mNear (-10.0f),
mFar (6.f), mFar (15.f),
mBBoxSize (5.f), mBBoxSize (35.f),
mLightSpaceMatrix(Matrix44f::Identity()) mLightSpaceMatrix(Matrix44f::Identity())
{ {
} }
void Initialize(); void Initialize();
void UpdateMatrices(); void UpdateMatrices();
void DrawGui();
}; };
struct RendererSettings; struct RendererSettings;

View File

@ -29,9 +29,6 @@ void Camera::UpdateMatrices() {
float width = mWidth * 0.5f * (mFar - mNear * 0.5f) * 0.001f; float width = mWidth * 0.5f * (mFar - mNear * 0.5f) * 0.001f;
float height = width * mHeight / mWidth; 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); mProjectionMatrix = Ortho(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, mNear, mFar);
} else { } else {
mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar); mProjectionMatrix = Perspective(mFov, mWidth / mHeight, mNear, mFar);
@ -286,8 +283,8 @@ void RenderTarget::Initialize(int width, int height, int flags) {
void RenderTarget::Bind() { void RenderTarget::Bind() {
assert(glIsFramebuffer(mFrameBufferId)); assert(glIsFramebuffer(mFrameBufferId));
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; GLenum shadow_map_draw_buffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); glDrawBuffers(1, shadow_map_draw_buffers);
} }
void RenderTarget::Cleanup() { void RenderTarget::Cleanup() {
@ -412,14 +409,11 @@ void RenderTarget::RenderToLinearizedDepth(const float& near, const float& far,
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
Matrix44f model_view_projection = Matrix44f::Identity();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mDepthTexture); glBindTexture(GL_TEXTURE_2D, mDepthTexture);
// render depth texture // render depth texture
glUseProgram(mLinearizeDepthProgram.mProgramId); glUseProgram(mLinearizeDepthProgram.mProgramId);
mLinearizeDepthProgram.SetMat44("uModelViewProj", model_view_projection);
mLinearizeDepthProgram.SetFloat("uNear", near); mLinearizeDepthProgram.SetFloat("uNear", near);
mLinearizeDepthProgram.SetFloat("uFar", far); mLinearizeDepthProgram.SetFloat("uFar", far);
mLinearizeDepthProgram.SetFloat("uIsOrthographic", is_orthographic ? 1.0f : 0.0f); mLinearizeDepthProgram.SetFloat("uIsOrthographic", is_orthographic ? 1.0f : 0.0f);