NOTE: this post has three basic problems. It assumes property 1 and 2 are true, and there is a missing piece at the end that keeps us from showing anything :)

This post results from a bunch of conversations with Dave Hart and the twitter hive brain. There are several ways to generate a random Lambertian direction from a point with surface normal

**N**. One way is inspired by a

cool paper by Sbert and Sandez where he simultaniously generated many form factors by repeatedly selecting a uniformly random 3D line in the scene. This can be used to generate a direction with a cosine density, an

idea first described, as far as I know, by Edd Biddulph.

I am going to describe it here using three properties, each of which I don't have a concise proof for. Any help appreciated! (I have algebraic proofs-- they just aren't enlightening--- hoping for a clever geometric observation).

**Property 1**:

Nusselt Analog: uniform random points on an equatorial disk projected onto the sphere have a cosine density. So in the figure, the red points, if all of them projected, have a cosine density.

**Property 2**:** (THIS PROPERTY IS NOT TRUE-- SEE COMMENTS)** The red points in the diagram above when projected onto the normal, will have a uniform density along it:

**Property 3:** For random points on a 3D sphere, as shown (badly) below, they when projected onto the central axis will be uniform on the central axis.

Now if we accept Property 3, we can first generate a random point on a sphere by first choosing a random phi uniformly theta = 2*PI*urandom(), and then choose a random height from negative 1 to 1, height = -1 + 2*urandom()

In XYZ coordinates we can convert this to:

z = -1 + 2*urandom()

phi = 2*PI*urandom()

x = cos(phi)*sqrt(1-z*z)

y = sin(phi)*sqrt(1-z^2)

Similarly from

** property 2 **we can given a random point (x,y) on a unit disk in the XY plane, we can generate a direction with cosine density when

** N **= the z axis:

(x,y) = random on disk

z = sqrt(1-x*x-y*y)

To generate a cosine direction relative to a surface normal

**N,** people usually construct a local basis, ANY local basis, with tangent and bitangent vectors

**B** and

** T** and change coordinate frames:

get_tangents(B,T,N)

(x,y) = random on disk

z = sqrt(1-x*x-y*y)

direction = x*B + y*T + z*N

There is f

inally a compact and robust way to write get_tangents. So use that, and your code is fast and good.

But can we do this show that using a uniform random sphere lets us do this without tangents?

So we do this:

P = (x,y,z) = random_on_unit_sphere

D = unit_vector(N + P)

So

**D **is the green dot while (

**N+P**) is the red dot:

So is there a clever observation that the green dot is either 1) uniform along **N, **or 2, uniform on the disk when projected?