Given a surface Normal vector of an intersection point, how can one generate a random direction vector that is guaranteed to be in the visible hemisphere? The way I am currently doing this is to sample a random direction vector d and dot it with the Normal and keep that vector if the dot product is greater than 0. This method is not guaranteed to generate a vector in the visible hemisphere of BRDF as ~50% of the random vectors would have a 0 or negative dot product result.

I saw somewhere that there is a way to transform the randomly generated vector d to place it in the visible hemisphere using a transformation matrix but I don't know how to do it. Can someone write a [pseudo]code for how one generate a direction vector using the transformation method?


1 Answer 1


If it’s on the wrong side of the normal, you don’t have to throw it away—negating it will give you a vector that’s in the visible hemisphere.

Answering your comment, to get a vector that’s within some angle θ of the normal, this should work (GLSL):

vec3 direction(vec3 normal, vec2 randomValues, float maxTheta) {
    // pick an orthogonal tangent vector using the method described here: http://lolengine.net/blog/2013/09/21/picking-orthogonal-vector-combing-coconuts
    vec3 tangent = (normal.x > normal.z) ? vec3(-normal.y, normal.x, 0.0) : vec3(0.0, -normal.z, normal.y);
    // and a bitangent vector orthogonal to both
    vec3 bitangent = cross(normal, tangent);

    float phi = 2.0 * PI * randomValues.x;
    float theta = randomValues.y * maxTheta;
    float sinTheta = sin(theta);
    return tangent * cos(phi) * sinTheta + bitangent * sin(phi) * sinTheta + normal * cos(theta);
  • 1
    $\begingroup$ Thanks. I think that's a super simply and effective way of doing what I explained. However, what if the goal is to generate random direction vectors that are within θ degrees of the Normal? $\endgroup$
    – Amir
    Feb 2, 2021 at 21:06
  • 1
    $\begingroup$ Added a way to do that to the answer. $\endgroup$ Feb 2, 2021 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.