2
$\begingroup$

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.

Example of current situation

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

Situation with slightly changed normal

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.

$\endgroup$
4
$\begingroup$

If your plane has a normal of $\begin{pmatrix}0 & 0 & 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 & 0 & 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) < dot(b, b) ? b : a;

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

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

  …

    vec3 u = computePrimaryTexDir(normal);
    vec3 v = cross(n, u);
$\endgroup$
  • 1
    $\begingroup$ This worked perfectly for my situation. It's been a while since my last Linear Algebra class, and my google-fu was failing me, so this is greatly appreciated! $\endgroup$ – Czorio Dec 9 '18 at 17:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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