How do I convert a hit on an infinite plane to UV coordinates for texturing in a Raytracer? I am trying to convert a ray hit on an infinite plane, defined by an origin and a normal vector, into UV coordinates, so I can find the appropriate texel at that point.

Code I have is close to functional, however, when the plane has a normal of (0, 0, -1) the result is a plain white plane.

The code that calculates the UV coordinates is pasted below:

// Calculate UV coordinates for the texture
vec3 u = vec3( normal.y, -normal.x, 0 ).normalized();
vec3 v = normal.cross( u );

h.u = u.dot( h.coordinates );
h.v = v.dot( h.coordinates );


h is a Hit struct that stores relevant data from a ray-primitive intersection, coordinates is the vec3 where the intersection occurred.

The current situation is shown in the following image; The floor plane properly shows the texture, however, the back wall does not.



However, when I change the normal of the back wall ever so slightly, the texture appears



In image 1 the normal of the back plane was (0, 0, -1), while it was (0.0001, 0, -1) in the second image.

I have been trying to figure this one out, but I am hitting a dead end.
If your plane has a normal of $\begin{pmatrix}0 &amp; 0 &amp; z\end{pmatrix}^T$, then your computation

vec3 u = vec3( normal.y, -normal.x, 0 ).normalized();
vec3 v = normal.cross( u );


will result in u and v both being $\begin{pmatrix}0 &amp; 0 &amp; 0\end{pmatrix}^T$.

A more general approach would be, for example, to compute the cross product of your normal with each of the three base vectors and use whichever result happens to be the longest as your direction for u:

vec3 computePrimaryTexDir(vec3 normal)
{
    vec3 a = cross(normal, vec3(1, 0, 0));
    vec3 b = cross(normal, vec3(0, 1, 0));

    vec3 max_ab = dot(a, a) &lt; dot(b, b) ? b : a;

    vec3 c = cross(normal, vec3(0, 0, 1));

    return normalize(dot(max_ab, max_ab) &lt; dot(c, c) ? c : max_ab);
}

  …

    vec3 u = computePrimaryTexDir(normal);
    vec3 v = cross(n, u);