I'm trying to render the Sponza scene using the Cook-Torrance BRDF Model Plugged with the GGX Normal Distribution, Gemoetry Schlick and fresnel Schlick approximation and a punctual point light. When rendered I get these artifacts
I don't know why these fragments in the yellow boxes are shadowed although everything in the Gbuffer looks normal. Here is the positions map
diffuse map
normal map
roughness map
metallness map
and finally the Ambient Occlusion
and here the fragment shader used to render the scene
#version 440 core
const float PI = 3.14159265359f;
struct PointLight
{
vec3 light_position;
vec3 light_intensity;
float radius;
};
uniform sampler2D position_map;
uniform sampler2D normal_map;
uniform sampler2D diffuse_map;
uniform sampler2D roughness_map;
uniform sampler2D metalness_map;
uniform sampler2D ao_map;
uniform PointLight pointlight;
in vec2 o_uv;
out vec4 final_color;
// NDF
float GGX_Distribution(float roughness, vec3 normal, vec3 halfway)
{
float numerator = pow(roughness, 4.0f);
float NdotH = max(dot(normal, halfway), 0.0f);
float denominator = PI * pow((NdotH * NdotH * (numerator - 1) + 1), 2.0f);
return numerator / denominator;
}
// Schlick-GGX
float SchlickGGX(vec3 normal, vec3 dir, float roughness)
{
float k_numerator = roughness + 1;
float k = (k_numerator * k_numerator) / 8.0f;
float numerator = max(dot(normal, dir), 0.0f);
float denominator = numerator * (1.0f - k) + k;
return numerator / denominator;
}
float GeometrySchlickGGX(vec3 normal, vec3 lightdir, vec3 viewdir, float roughness)
{
return SchlickGGX(normal, lightdir, roughness) * SchlickGGX(normal, viewdir, roughness);
}
vec3 F_Schlick(vec3 F0, vec3 lightdir, vec3 halfway)
{
float LdotH = max(dot(lightdir, halfway), 0.0f);
return F0 + (1.0f - F0) * pow((1.0f - LdotH), 5.0f);
}
vec3 PointLightIllum(PointLight pointlight, vec3 fragPos, float roughness,
vec3 diffuse, float metalness, vec3 normal)
{
vec3 lightDir = normalize(pointlight.light_position - fragPos);
vec3 viewDir = normalize(-fragPos);
vec3 halfway = normalize(lightDir + viewDir);
float d = length(pointlight.light_position - fragPos);
float attenuation = 1.0f / ((d * d) + 0.001f);
float NdotL = max(dot(lightDir, normal), 0.0f);
float NdotV = max(dot(viewDir, normal), 0.0f);
vec3 F0 = vec3(0.04);
F0 = mix(F0, diffuse, metalness);
// Specular Reflections
vec3 F = F_Schlick(F0, lightDir, halfway);
// Shadowing and masking
float G = GeometrySchlickGGX(normal, lightDir, viewDir, roughness);
float D = GGX_Distribution(roughness, normal, halfway);
vec3 numerator = F * G * D;
float denominator = 4.0f * NdotV * NdotL + 0.0001f;
vec3 BRDF = numerator / denominator;
vec3 spec = BRDF * pointlight.light_intensity * attenuation * NdotL;
vec3 diff = (diffuse / PI) * pointlight.light_intensity * attenuation * NdotL * (1.0f - metalness);
diff *= vec3(1.0f) - F;
vec3 Lo = spec + diff;
return Lo;
}
void main()
{
vec3 fragPos = texture(position_map, o_uv).rgb;
vec3 normal = normalize(texture(normal_map, o_uv).rgb);
vec3 diffuse = texture(diffuse_map, o_uv).rgb;
float roughness = texture(roughness_map, o_uv).r;
float metalness = texture(metalness_map, o_uv).r;
float ao = texture(ao_map, o_uv).r;
// Ambient occlusion
float ambient_intensity = 0.2f;
vec3 ambient = diffuse * ambient_intensity * ao;
vec3 direct = PointLightIllum(pointlight, fragPos, roughness, diffuse, metalness, normal);
vec3 indirect = ambient;
final_color = vec4(indirect + direct, 1.0f);
}
the vertex shader is a simple shader where i just render a quad with the size of screen and use its UVs to sample the textures. Could Someone tell why i'm having this artifact and how to resolve it?