4

I'm reading through this article, and more specifically I'm trying to derive the equation that would explain the implementation the following shader (still in the same article):

#version 330 core
out vec4 FragColor;
in vec3 localPos;

uniform samplerCube environmentMap;
uniform float roughness;

const float PI = 3.14159265359;

float RadicalInverse_VdC(uint bits);
vec2 Hammersley(uint i, uint N);
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);

void main()
{       
    vec3 N = normalize(localPos);    
    vec3 R = N;
    vec3 V = R;

    const uint SAMPLE_COUNT = 1024u;
    float totalWeight = 0.0;   
    vec3 prefilteredColor = vec3(0.0);     
    for(uint i = 0u; i < SAMPLE_COUNT; ++i)
    {
        vec2 Xi = Hammersley(i, SAMPLE_COUNT);
        vec3 H  = ImportanceSampleGGX(Xi, N, roughness);
        vec3 L  = normalize(2.0 * dot(V, H) * H - V);

        float NdotL = max(dot(N, L), 0.0);
        if(NdotL > 0.0)
        {
            prefilteredColor += texture(environmentMap, L).rgb * NdotL;
            totalWeight      += NdotL;
        }
    }
    prefilteredColor = prefilteredColor / totalWeight;

    FragColor = vec4(prefilteredColor, 1.0);
}  

Which is my understanding suppose to implement the computation of the integral

$$ I = \int_{\Omega} L(\omega_i)d\omega_i $$

However I'm not entirely sure since NdotL is also used in the computation so I might be wrong.

It seems to me the idea is given $N$ to sample a random halfway vector $H$, and based on this we can construct, by reflection, the light direction vector $L$, which would be random as well by construction. The article also mentions that $H$ is sampled from a normal distribution.

But anyway suppose I have samples $H^{1} ,\ldots, H^{N}$ and therefore $L^{1},\ldots, L^{N}$ samples, the latter I suppose would define $\omega_{i}^{1} \ldots, \omega_{i}^{N}$ (solid angles).

By importance sampling

$$ I \approx \frac{1}{N} \sum_{j=1}^{N} \frac{L(\omega_i^{j})}{pdf(\omega_i^{j})} \;\;\;\; (1) $$

If what I wrote is correct than I don't know where the dot product and the normalization factor

$$ W = \sum_{j=1}^{N} N\cdot L^{j} $$

comes from, namely how do I go from $(1)$ to

$$ I \approx \frac{\sum_{j=1}^{N}L(\omega_i^{j}) N \cdot L^{j}} {\sum_{j=1}^{N} N \cdot L^{j}} $$

Update: I'm pretty sure many of you know this already, but the shader above is for a pre-filtered environment map. Which means in this context the actual integral should be given by

$$ I(N) = \int_{\Omega} L(\omega_i) N \cdot L d\omega $$

This explains the factor $N \cdot L$ in the shader, the distribution function used is the GGX distribution, I assume plugging this stuff together might give me the formula.

Just updating because it might give a better clue.

user8469759
  • 556
  • 1
  • 6
  • 17
  • Looks wrong honestly, you cannot get to (1) by importance sampling in any sane manner that I can think of. They are using ggx sampling and do not divide by the pdf, but rather by some sum. Now if they are using a biased estimator of some form, then that's another matter, but I do not believe this was mentioned in the article. I am inclined to believe it's just wrong, try contacting the author. – lightxbulb May 24 '19 at 22:15
  • They do mention in the article they divide on purpose for the total sum though. – user8469759 May 24 '19 at 22:27
  • Also if you, like me, think it's wrong... What would be the right montecarlo estimator then? – user8469759 May 24 '19 at 22:28
  • The shader is a cut and paste of the one shown at page 6 here: https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf . – user8469759 May 24 '19 at 22:57
  • "As shown in the code below, we have found weighting by coslk achieves better results1. 1This weighting is not present in Equation 7, which is left in a simpler form" - from the article you linked. They have not provided a reasoning beyond "achieves better results". Or at least I cannot find the part where they formally motivate this. – lightxbulb May 25 '19 at 04:42
  • As for the correct estimator (not split sum) and code, you can find it just above the copy pasted part in the self shadow article you linked, in the Image based lighting section. Note that what they are estimating is not even L weighted by some cosine term, since they do not divide by the GGX's importance sampling pdf, then it's implicitly in the estimated integral. – lightxbulb May 25 '19 at 04:51
  • I meant the "correct estimator" for the factor in question in the split and sum. – user8469759 May 26 '19 at 12:25
  • It's also in the article, you can see it where they split the sums, they just don't write code for it. – lightxbulb May 27 '19 at 07:41
  • Well anyway, I'd really like to get in touch with the author of that shader, but I can't find any e-mail address. I'm not either sure that was actually published in some scientific paper. – user8469759 May 29 '19 at 10:20
  • Don't think too hard about it. A large part of real-time techniques have no physical basis and were usually tweaked by hand. You can regard the weighting as some kind of biased estimator I believe, but I don't believe it will make much sense physically even if I write out the analytical formulation. – lightxbulb May 30 '19 at 10:56
  • What do you mean with biased estimator? – user8469759 May 30 '19 at 10:58
  • An estimator with non-zero bias. Look up bias of an estimator, it's a math term. – lightxbulb May 31 '19 at 17:04

0 Answers0