I am currently experiencing a very obvious artifact that occurs when looking at objects on very grazing angles

Here is a picture of the artifact: artifact

I noticed that the issue was coming from my implementation of Cook-Torrance's Specular BRDF.

Here is the equation for the Cook-Torrance Specular BRDF: Cook-Torrance Specular BRDF

More specifically, calculating the denominator is causing the issue:

float denominator = 4 * max(dot(viewDir, normal), 0.0) * max(dot(lightDir, normal), 0.0) + 0.001;  // Prevents any division by zero

When I change the calculation of dot(viewDir, normal) to dot(halfway, normal), the artifact disappears:

float denominator = 4 * max(dot(halfway, normal), 0.0) * max(dot(lightDir, normal), 0.0) + 0.001;  // Prevents any division by zero

But this equation is no longer correct. I was wondering if anyone knows why my implementation causes these artifacts?

If you want to see my fragment shader you can find the code here:


Thank you!

  • 2
    $\begingroup$ Have you tried calculating the TBN in the fragment shader? When calculating it in the vertex shader, OpenGL will linearly interpolate the matrix for use in the fragment shader and that might cause the artifacts. Do make sure that you normalize the tangent, bitangent and normal in the fragment shader before using them (again because of the linear interpolation). $\endgroup$ – bram0101 Oct 9 '18 at 6:36
  • $\begingroup$ Yes I tried to do this in the fragment shader and normalized the vectors before, and I still get these strange artifacts $\endgroup$ – Brady Jessup Oct 9 '18 at 13:55
  • $\begingroup$ Tangents are multiplied by the model matrix, as they dont suffer from non-uniform scale disortion as normal vector do. Also, you do need a vertex normal and a normal vector extracted from the normal map, however, I see you are applying the normalization (normalize(normal * 2.0f - 1.0f)) to the same vector you used to create the TBN matrix $\endgroup$ – Nadir Oct 10 '18 at 14:34
  • $\begingroup$ I thought the tangents and bitangents would also suffer from possibly being non-orthogonal to each other if scaled non-uniformly. Also I edited my fragment shader code above to showcase that I am actually sampling the normal from the normal map. My bad! $\endgroup$ – Brady Jessup Oct 10 '18 at 16:51
  • 1
    $\begingroup$ Have you identified which part of the code generates the color of the artifact? Have you tried to reduce your shader to a minimal reproduce case? I wouldn't be surprised if it was due to either a normal facing away from light, or a nearly 0 but negative parameter to a pow() function. $\endgroup$ – Julien Guertault Oct 11 '18 at 4:35

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.