<p>Well I'm embarrassed to say that but turns out the problem was with the format of the normals render target instead of making it <strong>GL_RGB32F</strong> I accidentally made it <strong>GL_RGB</strong> causing the normals to be clipped to range 0 -&gt; 1 instead of -1 -&gt; 1 causing some fragments to be shadowed due to incorrect lighting calculations.</p>

CC BY-SA 4.0
2022-07-12T17:53:48.123Z
Btw, you can use R10G10B10A2 format for normals to use less space than RGB32F (4 vs 12 bytes per pixel) while having more precision than with RGB8 format (10 vs 8 bits). You'll still have to manually remap normals from [-1,1] to [0,1] and back, though.
lisyarus
CC BY-SA 4.0
2022-07-11T15:05:47.183Z
2022-07-11T15:05:47.183Z
Mohamed Hashem
<p>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</p>
<p><a href="https://i.sstatic.net/djbxo.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/djbxo.jpg" alt="final scene" /></a></p>
<p>I don't know why these fragments in the yellow boxes are shadowed although everything in the <strong>Gbuffer</strong> looks normal. Here is the <strong>positions map</strong></p>
<p><a href="https://i.sstatic.net/WP5Jh.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/WP5Jh.png" alt="positions" /></a></p>
<p>diffuse map</p>
<p><a href="https://i.sstatic.net/t5KTS.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/t5KTS.jpg" alt="enter image description here" /></a></p>
<p>normal map</p>
<p><a href="https://i.sstatic.net/kzogt.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/kzogt.jpg" alt="enter image description here" /></a></p>
<p>roughness map</p>
<p><a href="https://i.sstatic.net/2KyA9.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/2KyA9.jpg" alt="enter image description here" /></a></p>
<p>metallness map</p>
<p><a href="https://i.sstatic.net/F2VTf.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/F2VTf.png" alt="enter image description here" /></a></p>
<p>and finally the Ambient Occlusion</p>
<p><a href="https://i.sstatic.net/FXkwr.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/FXkwr.jpg" alt="enter image description here" /></a></p>
<p>and here the fragment shader used to render the scene</p>
<pre><code>#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);
}
</code></pre>
<p>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?</p>

CC BY-SA 4.0
2022-07-11T14:26:10.473Z
Is your camera at the origin? " vec3 viewDir = normalize(-fragPos);"
pmw1234
CC BY-SA 4.0
2022-07-11T14:33:53.927Z
yes i have a fixed camera centered at the origin
Mohamed Hashem
<opengl><glsl>
Artifacts while rendering sponza scene
Mohamed Hashem
# Artifacts while rendering sponza scene

(Asked by: username_0 on 2022-07-10)

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

[![final scene](https://i.sstatic.net/djbxo.jpg)](https://i.sstatic.net/djbxo.jpg)

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**

[![positions](https://i.sstatic.net/WP5Jh.png)](https://i.sstatic.net/WP5Jh.png)

diffuse map

[![enter image description here](https://i.sstatic.net/t5KTS.jpg)](https://i.sstatic.net/t5KTS.jpg)

normal map

[![enter image description here](https://i.sstatic.net/kzogt.jpg)](https://i.sstatic.net/kzogt.jpg)

roughness map

[![enter image description here](https://i.sstatic.net/2KyA9.jpg)](https://i.sstatic.net/2KyA9.jpg)

metallness map

[![enter image description here](https://i.sstatic.net/F2VTf.png)](https://i.sstatic.net/F2VTf.png)

and finally the Ambient Occlusion

[![enter image description here](https://i.sstatic.net/FXkwr.jpg)](https://i.sstatic.net/FXkwr.jpg)

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?

**Tags:** opengl, glsl

> **Comments:**
> **username_1**: Is your camera at the origin? " vec3 viewDir = normalize(-fragPos);"  
> **username_0**: yes i have a fixed camera centered at the origin  

---

## 1 answers

### Answer by username_0 on 2022-07-11. Score: 3 | Accepted answer

Well I'm embarrassed to say that but turns out the problem was with the format of the normals render target instead of making it **GL\_RGB32F** I accidentally made it **GL\_RGB** causing the normals to be clipped to range 0 -> 1 instead of -1 -> 1 causing some fragments to be shadowed due to incorrect lighting calculations.

> **Comments:**
> **username_2**: Btw, you can use R10G10B10A2 format for normals to use less space than RGB32F (4 vs 12 bytes per pixel) while having more precision than with RGB8 format (10 vs 8 bits). You'll still have to manually remap normals from [-1,1] to [0,1] and back, though.  

---

