diff --git a/data/shaders/fs_deferred_lighting.glsl b/data/shaders/fs_deferred_lighting.glsl index 9b9a11e..6b6f3f7 100644 --- a/data/shaders/fs_deferred_lighting.glsl +++ b/data/shaders/fs_deferred_lighting.glsl @@ -17,11 +17,58 @@ uniform vec3 uViewPosition; uniform vec3 uLightDirection; uniform mat4 uLightSpaceMatrix; +uniform mat4 uViewToLightSpaceMatrix; in vec2 ioFragTexCoords; out vec3 outColor; +float ShadowCalculationPCF(vec4 frag_pos_light_space, vec3 frag_normal_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.02 * (1.0 - dot(frag_normal_light_space, 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 frag_normal_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.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(frag_normal_light_space, uLightDirection)), 0.003); +#endif + + return current_depth - bias > closest_depth ? 1.0 : 0.0; +} + void main() { vec3 color = texture(uColor, ioFragTexCoords).rgb; vec3 normal = texture (uNormal, ioFragTexCoords).xyz; @@ -46,5 +93,13 @@ void main() { vec3 specular = spec * vec3(0.5); // shadow - outColor = ambient + (diffuse + specular); + + // TODO: transform to light space + vec4 position_light_space = uViewToLightSpaceMatrix * vec4(position, 1.0); + vec3 normal_light_space = normal; + + float shadow = ShadowCalculationPCF(position_light_space, normal); + outColor = ambient + (1.0 - shadow) * (diffuse + specular); + +// outColor = ambient + (diffuse + specular); } diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 234bc77..4d12d8b 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -681,8 +681,10 @@ void Renderer::RenderGl() { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture); - mDeferredLighting.SetInt("uDepth", 3); + mDeferredLighting.SetInt("uShadowMap", 3); mDeferredLighting.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix); + Matrix44f view_to_light_matrix = mCamera.mViewMatrix.inverse() * mLight.mLightSpaceMatrix; + mDeferredLighting.SetMat44("uViewToLightSpaceMatrix", view_to_light_matrix); // TODO: remove and reconstruct position from depth glActiveTexture(GL_TEXTURE4); @@ -693,11 +695,6 @@ void Renderer::RenderGl() { Matrix33f view_mat_rot = mCamera.mViewMatrix.block<3,3>(0,0); view_mat_rot = view_mat_rot.transpose(); Vector3f light_direction = view_mat_rot * mLight.mDirection.normalized(); - -// gLog ("Light direction %3.4f, %3.4f, %3.4f", -// light_direction[0], -// light_direction[1], -// light_direction[2]); mDeferredLighting.SetVec3("uLightDirection", light_direction); mDeferredLighting.SetVec3("uViewPosition", mCamera.mEye);