As the title suggests I'm trying to implement the last images of the "Microfacet Models for Refraction through Rough Surfaces" Paper by Walter et al. in OpenGL
I "think" (I had to put that into quotation marks) I know how the microfacet model should work and hopefully am only stuck on practical execution.
So I started by implementing the GGX formulas for the Normal Distribution, Fresnel and Geometry Function.
Initially and still I'm not so sure how to get the color of the object behind the glass into the formulas. My first thought was to create a cubemap around the slate of glass and then use the outgoing direction vectors (o_t and o_r) to sample the cubemap. But then I'm still not so sure how to incorporate that into the larger picture. Going by my first thought again I just multiplied the result of the BTFD with the sample of the o_t vector but apparently the BTDF was really big so the whole slate turned white (possible bug?). After dividing the result a few times some washed-up version of what was supposed to show up appeared.
Also I think I read somewhere that the reflection and transmission should be handled seperatly depending on the result of the Fresnel formula. Or should it be handled at the same time (possibly somethink like : BRDF * sample_of_reflection + BTDF * sample_of_refraction)?
And another thing I found curious is the given equation for sampling:
$\theta = arctan(a * sqrt(rand1) / sqrt(1 - rand1))$
$\phi = 2 * \pi * rand2$
After some playing around with this function I noticed that is basically something akin to a gaussian distribution pointing towards the positive z-axis. But shouldn't the distribution give samples which are distributed around the surface normal?
I'm wondering if I have to add an additional pair of quotation marks to my earlier statement...
So anyway here is the pseudocode for my implementation until now:
for(#samplecount)
{
//get a sample m
vec3 m = drawsample();
//calculate normal and incoming vector
vec3 i = normalize(viewPosition - fragmentPosition);
vec3 n = normalize(Normal);
// calculate outgoing vector
vec3 o_r = calculate_like_paper();
vec3 o_t = calculate_like_paper();
//sample cubemap
vec3 reflection = sampleCubemap();
vec3 refraction = sampleCubemap();
//calculate halfvectors
vec3 h_r = calculate_like_paper();
vec3 h_t = calculate_like_paper();
//calculate NDF, Fresnel and Geometry
float D = GGX_D(h_r);
float G = GGX_G(i, o_r, h_r);
float F = GGX_F(i, h_r);
//calculate BSDF, BRDF & BTDF
float BRDF = F * G * D / (4.0 * abs(dot(i, n)) * abs(dot(o_r, n)));
float BTDF = longFormula();
float BSDF = BRDF + BTDF
vec3 result += BRDF * reflection + BTDF * refraction //?
}
result /= #samplecount;
Thank you if you take your time to answer and I'm relatively new to StackExchange so I could definitely do with some feedback to improve the way I ask questions.
Edit: So if anyone found this question and has similar questions Epic Games has some nice notes on this topic: https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf