Here's an efficient way to generate uniform samples on the unit sphere attributed to Marsaglia (1972).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | internal v3 SampleSphere(random_series *Series) { v3 Result = {}; f32 X1, X2, SquaresSum, SquareRootTerm; do { X1 = RandomBilateral(Series); X2 = RandomBilateral(Series); SquaresSum = Square(X1) + Square(X2); } while (SquaresSum >= 1.0f); SquareRootTerm = 2*SquareRoot(1 - SquaresSum); Result.x = X1*SquareRootTerm; Result.y = X2*SquareRootTerm; Result.z = 1 - 2*SquaresSum; return(Result); } |
You can flip the sample's position according to its dot product with a normal as before.