Cook-Torrance problems

Hi guys

I calculate Cook-Torrance BRDF. It look okay and mostly fine but i found some problem with geometry term.
Code for “G” term are:

float GeometrySchlickGGX(float NdotV, float k)
{

  • float nom = NdotV;*
  • float denom = NdotV * (1.0 - k) + k;*
  • return nom / denom;*
    }

float GeometrySmith(vec3 N, vec3 V, vec3 L, float k)
{

  • float NdotV = max(dot(N, V), 0.0);*
  • float NdotL = max(dot(N, L), 0.0);*
  • float ggx1 = GeometrySchlickGGX(NdotV, k);*
  • float ggx2 = GeometrySchlickGGX(NdotL, k);*
  • return ggx1 * ggx2;*
    }

Where k = roughness and calculated as:
float r = (roughness + 1.0);
float k = (rr) / 8.0;*

Here’s the problem. In this case i only output “G” term itself without any other calculations (complited calculations will also have same problem)
Notice how area which should stay lit becomes pure black.

Look at “lit” area.

Now those “lit” area becomes black.

Im not really and fully understand BRDF theory and code, so doesnt really sure if its a problem with those G term calculations, or its a generic Cook-Torrance problem?
I guess those behavior are probably correct, cause surface normal of those problematic area are more like look to light position, and camera look from kind of “back side”. I mean something like this:


But again im nor sure does it really should work tthis way.

Entire code are from

https://nccastaff.bournemouth.ac.uk/jmacey/OpenGL/shaders/PBR/pbr.html

1 Like

UPDATE:
Well, looks like problem are even more complicated.

  1. Shader are works perfectly fine in “surface” material domain. In this case N (normal) for entire calculations are normalized normal map texture transformed from tangent to world space.

  2. In post-process material domain (and yeah i need those to work inside PP material) i use SceneTexture: World normal as is (after Normalize node) for all N in the shader.

Now im complitely stuck. Why SceneTexture: World normal doesnt work? :confused:

1 Like

Problem was solved.

I was forget about this max:
vec3 specular = numerator / max(denominator, 0.001);

:roll_eyes:

1 Like