Hello guys, these past weeks I've been trying to implement a PBR shader and OMG there are so many little details. First I started reading this article: https://learnopengl.com/PBR/Theory
because it had a lot of good explanations and sample code, and did A LOT of googling for the stuff that wasn't clear enough. Right now I am very confused about why the fresnel term uses the dot product between de halfway vector and the view vector. From theory I thought that the fresnel computes the amount of light that should reflect off a surface depending on the viewing angle and the surface normal, and there are a lot of articles explaining it like that:
- https://learnopengl.com/PBR/Theory
- https://docs.unrealengine.com/en-US/Engine/Rendering/Materials/HowTo/Fresnel/index.html
- https://en.wikipedia.org/wiki/Schlick's_approximation (in the first paragraphs)
And I was happy with that knowledge until I started to discover a lot of articles (and even that wiki one in the last sentence) that actually tell you to use the dot product between the halfway vector and light direction.
- http://filmicworlds.com/blog/everything-has-fresnel/ (this one just says that it got the formula from the gpu gems article https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch14.html which unfortunately doesn't give details about that)
- http://www.codinglabs.net/article_physically_based_rendering_cook_torrance.aspx
- https://computergraphics.stackexchange.com/questions/2494/in-a-physically-based-brdf-what-vector-should-be-used-to-compute-the-fresnel-co (there are really good answers here but I couldn't wrap my head around)
I tried to read the original schlick's paper but I'm the kind of person that can't really follow all that math without visual examples...
In the first image I'm using the dot(N,V) and visually it makes sense. In the second image I'm using the suggested dot(H,L) while having a point light behind the sphere, and I'm just confused, I can't understand what I'm looking at, and why is the normal not needed at all.
I have the feeling I may be mistunderstanding or mixing concepts, so I decided to come here and create a thread so maybe someone could explain it with more....simple words?
Also here is a code snippet of what I'm currently doing, but just for illustrative purposes ( I'm not looking for code, just some theory explanations):
void frag()
{
float NDF = DistributionGGX(N,H,roughness);
float G = GeometrySmith(N, V, L,roughness);
float3 F = SchlickFresnel(saturate(dot(V,H)??), F0);
float3 radiance = lightColor*attenuation*dot(N,L); // only have a single point light
float3 numerator = NDF * G * F;
float denominator = 4.0 * saturate(dot(N, V)) * saturate(dot(N, L));
float3 specular = numerator/ max(denominator, 0.001); //avoid division by 0
float3 kd = float3(1,1,1) - F; // if I understood correctly, ks is not needed as it is included in the F term
float3 diffuse = albedo/PI;
float3 irradiance = (kd * diffuse + specular) * radiance * NdotL;
}
I know there are a lot of posts talking about this, and I spent a lot of time reading those, but it wasn't entirely clear...so apologies for making another thread asking basically the same thing. Thanks for your time...cheers!