Skip to content

Instantly share code, notes, and snippets.

@spenceryonce
Created August 6, 2023 17:44
Show Gist options
  • Save spenceryonce/657c46b4393a425e67fe810bfe862a4f to your computer and use it in GitHub Desktop.
Save spenceryonce/657c46b4393a425e67fe810bfe862a4f to your computer and use it in GitHub Desktop.
calculateEyeRayTransformationMatrix Decoded

Eye Ray Transformation Matrix Decoded (GLSL)

Inigo Quillez has a function that calculates the eye ray transformation matrix for shaders and it looks like this:

mat3 calculateEyeRayTransformationMatrix( in vec3 ro, in vec3 ta, in float roll )
{
    vec3 ww = normalize( ta - ro );
    vec3 uu = normalize( cross(ww,vec3(sin(roll),cos(roll),0.0) ) );
    vec3 vv = normalize( cross(uu,ww));
    return mat3( uu, vv, ww );
}

which calculates a 3x3 transformation matrix that represents a coordinate system transformation for a camera in 3D space. This transformation is useful for ray tracing or other applications that require defining a camera's orientation and position. Here's a breakdown of the function:

Input Parameters:
  • ro: The position of the camera or the eye point in 3D space.
  • ta: The target or look-at point, defining where the camera is looking.
  • roll: The roll angle around the viewing direction, allowing the camera to tilt sideways.
Calculating the Basis Vectors:
  • ww: The forward direction of the camera, calculated by normalizing the difference between the target and the camera position. This gives the direction in which the camera is looking.
  • uu: The right direction of the camera, calculated using the cross product between ww and a vector created from the sine and cosine of the roll angle. This creates a vector that is perpendicular to ww, and the roll angle controls the tilt of the camera around its viewing direction.
  • vv: The up direction of the camera, calculated using the cross product between uu and ww. This gives a vector that is perpendicular to both uu and ww, and hence defines the upward direction in the camera's local coordinate system.
Returning the Transformation Matrix:

Finally, the function constructs and returns a 3x3 matrix using the three basis vectors uu, vv, and ww. This matrix represents the transformation from the world coordinate system to the camera's local coordinate system. The resulting matrix can be used to transform directions or positions in 3D space relative to the camera's orientation and position. It's common to use this type of transformation in 3D graphics, especially in ray tracing, where you need to compute the direction of rays emanating from the camera's position toward the scene.

Explanation

While the above code is precise and small, for newcomers to shaders, it is hard to understand. To fully visualize what is happening above, I am going to rename the variables to better represent their roles within the function:

  • ro becomes cameraPosition: the position of the camera in 3D space.

  • ta becomes targetPosition: the point in space the camera is looking at.

  • roll becomes rollAngle: the angle for the roll transformation.

  • ww becomes forwardDirection: the forward direction of the camera.

  • uu becomes rightDirection: the right direction of the camera.

  • vv becomes upDirection: the up direction of the camera.

Which gives us this new code:

mat3 calculateEyeRayTransformationMatrix(in vec3 cameraPosition, in vec3 targetPosition, in float rollAngle)
{
    vec3 forwardDirection = normalize(targetPosition - cameraPosition);
    vec3 rightDirection = normalize(cross(forwardDirection, vec3(sin(rollAngle), cos(rollAngle), 0.0)));
    vec3 upDirection = normalize(cross(rightDirection, forwardDirection));
    return mat3(rightDirection, upDirection, forwardDirection);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment