Benjamin Keinert
sent a nice note in regards to an earlier post to quickly get "lambertianish" rays. He empirically confirmed it is exactly lambertian. Cool, and thanks Benjamin I always believe such demonstrations more convincing that proofs which can have subtle errors (fine, yes, I am an engineer). I include his full email with his permission.

I think I found a simple
informal "engineer's style proof" that it is indeed lambertian (assuming
the sample rejection method yields a uniform distribution on a sphere,
which it should).

Instead of using a rejection method I picked the uniform distribution on
a sphere using spherical fibonacci point sets [2] and constructed a
cosine hemisphere sampling variant of it.

Without the loss of generality it should be sufficient to show that the
mapping is lambertian for a single normal (0,0,1) - given uniformly
distributed points on a sphere and rotational invariance.

Sorry, rapid prototyping code, oldschool OpenGL, PHI = (sqrt(5.0)*0.5 +
0.5):

// PDF: 1/(4*PI)

float3 uniformSampleSphereSF(float i, float n) {

float phi = 2*PI*(i/PHI);

float cosTheta = 1 - (2*i+1)/n;

float sinTheta = sqrt(1 - cosTheta*cosTheta);

return float3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);

}

// PDF: cos(theta)/PI

float3 cosineSampleHemisphereSF(float i, float n) {

float phi = 2*PI*(i/PHI);

float cosTheta = sqrt(1 - (i+0.5)/n);

float sinTheta = sqrt(1 - cosTheta*cosTheta);

return float3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);

}

[...]

void test() {

[...]

// Enable additive blending etc.

[...]

uint n = 1024;

glBegin(GL_POINTS);

for (uint i = 0; i < n; ++i) {

glColor4f(0,1,0,1); // Green

float3 p = normalize(uniformSampleSphereSF(i, n) + float3(0,0,1));

glVertex3fv(&p[0]);

glColor4f(1,0,0,1); // Red

float3 q = cosineSampleHemisphereSF(i, n);

glVertex3fv(&q[0]);

// Additive blending => Yellow == "good"

}

glEnd();

}

This little function results in the attached image (orthogonal
projection of cosine distributed points on a hemisphere -> uniformly
distributed points on a circle).

With some more effort one can show that
normalize(uniformSampleSphereSF(i, n) + float3(0,0,1)) =
cosineSampleHemisphereSF(i, n) - instead of using additive blending.

[1] http://psgraphics.blogspot.de/2014/09/random-diffuse-rays.html

[2] Spherical Fibonacci Point Sets for Illumination Integrals, Marques
et. al.

## 1 comment:

very informative for me.

Post a Comment