Choosing theta to be arccos(sqrt(rand1)) would not give you randomly distributed points on the surface of a unit sphere since the distribution of arccos(sqrt(rand1)) is nowhere uniform as it should be.
Given two random variates u and v, uniformly sampled from (0, 1), in spherical coordinates a random point would be:
theta = 2*pi * u <--- note, no arccos here
phi = arccos(2*v - 1)
Since it's a reflection from a surface, you only have to sample half of the spherical surface, so theta would rather be theta = pi * u.
Since the angle of reflection is random, it doesn't really matter where the light source is located, i.e. the result does not depend on the light vector L. You only have to chose the spherical coordinates so that the sampled hemisphere is on the outer side of the surface.
Another option:
- Draw a random point on the surface of the entire unit sphere (i.e.
theta = 2 * pi * u)
- Convert to Cartesian point vector coordinates
- Take the dot product of the normal and the point vector. If it's negative, repeat from step 1.
This would guarantee that you only sample from the hemisphere that faces the outer side of the surface.
You could also skip the spherical coordinates altogether and directly compute the Cartesian coordinates:
x = sqrt(1 - u^2) * cos(theta)
y = sqrt(1 - u^2) * sin(theta)
z = u
Here u is uniformly sampled from [-1, 1] (e.g. u = 2*v - 1 where v is uniformly sampled in [0, 1]) and theta is uniformly sampled from [0, 2*pi).
There is another method that does not use trigonometric functions at all (taken from here):
Take x1 and x2 uniformly sampled from [-1, 1]. If x1^2 + x2^2 < 1, then (if not, repeat the sampling):
x = 2 * x1 * sqrt(1 - x1^2 - x2^2)
y = 2 * x2 * sqrt(1 - x1^2 - x2^2)
z = 1 - 2 * (x1^2 + x2^2)