diff --git a/data/shaders/fs_default.glsl b/data/shaders/fs_default.glsl index ae8f39b..202582a 100644 --- a/data/shaders/fs_default.glsl +++ b/data/shaders/fs_default.glsl @@ -4,7 +4,14 @@ uniform vec4 uColor; uniform vec3 uLightDirection; uniform vec3 uViewPosition; uniform sampler2D uAlbedoTexture; + +#define USE_SAMPLER2D_SHADOW 1 + +#ifdef USE_SAMPLER2D_SHADOW +uniform sampler2DShadow uShadowMap; +#else uniform sampler2D uShadowMap; +#endif in vec3 ioFragPosition; in vec3 ioFragNormal; @@ -14,15 +21,49 @@ in vec4 ioFragPosLightSpace; out vec4 outColor; +float ShadowCalculationPCF(vec4 frag_pos_light_space) { + vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w; + projected_coordinates = projected_coordinates * 0.5 + 0.5; + + float current_depth = projected_coordinates.z; + + float bias = 0.00; + bias = max(0.005 * (1.0 - dot(ioFragNormal, uLightDirection)), 0.003); + + float shadow = 0.0; + vec2 texel_size = 1.0 / textureSize(uShadowMap, 0); + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { +#ifdef USE_SAMPLER2D_SHADOW + vec2 coordinate = projected_coordinates.xy + vec2(x, y) * texel_size; + float pcf_depth = texture(uShadowMap, vec3(coordinate, current_depth - bias)); +#else + float pcf_depth = texture(uShadowMap, projected_coordinates.xy).r; +#endif + shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0; + } + } + + shadow /= 9.0; + + return shadow; +} + float ShadowCalculation(vec4 frag_pos_light_space) { vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w; projected_coordinates = projected_coordinates * 0.5 + 0.5; - float closest_depth = texture(uShadowMap, projected_coordinates.xy).r; float current_depth = projected_coordinates.z; - float bias = max(0.05 * (1.0 - dot(ioFragNormal, uLightDirection)), 0.005); - bias = 0.0; + float bias = 0.01; + +#ifdef USE_SAMPLER2D_SHADOW + float closest_depth = texture(uShadowMap, vec3(projected_coordinates.xy, current_depth - bias)); +#else + float closest_depth = texture(uShadowMap, projected_coordinates.xy).r; + bias = max(0.005 * (1.0 - dot(ioFragNormal, uLightDirection)), 0.003); +#endif + return current_depth - bias > closest_depth ? 1.0 : 0.0; } @@ -47,7 +88,8 @@ void main() { vec4 specular = spec * vec4(0.5); // shadow - float shadow = ShadowCalculation(ioFragPosLightSpace); +// float shadow = ShadowCalculation(ioFragPosLightSpace); + float shadow = ShadowCalculationPCF(ioFragPosLightSpace); outColor = ambient + (1.0 - shadow) * (diffuse + specular); // // diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 3a1d2b3..e139e46 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -215,7 +215,7 @@ void Light::DrawGui() { // Renderer // void Renderer::Initialize(int width, int height) { - mDefaultTexture.MakeGrid(128, Vector3f (0.8, 0.8f, 0.8f), Vector3f (0.2f, 0.2f, 0.2f)); + mDefaultTexture.MakeGrid(128, Vector3f (0.8, 0.8f, 0.8f), Vector3f (0.7f, 0.7f, 0.7f)); gVertexArray.Initialize(1000, GL_STATIC_DRAW); gCoordinateFrameMesh.Initialize(gVertexArray, 6); @@ -411,7 +411,7 @@ void Renderer::RenderGl() { mLight.UpdateMatrices(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_DEPTH_TEST); - glCullFace(GL_FRONT); +// glCullFace(GL_FRONT); glUseProgram(mLight.mShadowMapProgram.mProgramId); if (mLight.mShadowMapProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); @@ -419,7 +419,7 @@ void Renderer::RenderGl() { RenderScene(mLight.mShadowMapProgram, mLight.mCamera); mLight.mShadowMapTarget.RenderToLinearizedDepth(mLight.mCamera.mNear, mLight.mCamera.mFar, mLight.mCamera.mIsOrthographic); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glCullFace(GL_BACK); +// glCullFace(GL_BACK); // Regular rendering glEnable(GL_LINE_SMOOTH); @@ -508,6 +508,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); program.SetInt("uShadowMap", 0); glActiveTexture(GL_TEXTURE1); diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index ef4ceb6..ee82034 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -36,7 +36,7 @@ struct Light { mPosition (Vector3f(0.f, 3, 0.0f)), mDirection (Vector3f(1.f, 1.f, 1.f)), mShadowMapBias (0.004f), - mShadowMapSize (1024), + mShadowMapSize (2048), mNear (-10.0f), mFar (15.f), mBBoxSize (35.f), diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 84d5abe..4916401 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -351,12 +351,15 @@ void RenderTarget::Resize(int width, int height) { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - 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_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // Set parameters so that we can set a shadow2DSampler + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + 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); + float border_color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture, 0);