<p>If your plane has a normal of <span class="math-container">$\begin{pmatrix}0 &amp; 0 &amp; z\end{pmatrix}^T$</span>, then your computation</p>

<pre><code>vec3 u = vec3( normal.y, -normal.x, 0 ).normalized();
vec3 v = normal.cross( u );
</code></pre>

<p>will result in <code>u</code> and <code>v</code> both being <span class="math-container">$\begin{pmatrix}0 &amp; 0 &amp; 0\end{pmatrix}^T$</span>.</p>

<p>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 <code>u</code>:</p>

<pre><code>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);
</code></pre>

CC BY-SA 4.0
2018-12-09T17:52:44.387Z
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!
Czorio
CC BY-SA 4.0
2018-12-09T16:45:50.090Z
2018-12-09T16:59:28.967Z
2018-12-09T16:59:28.967Z
Michael Kenzel
<p>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.</p>

<p>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.</p>

<p>The code that calculates the UV coordinates is pasted below:</p>

<pre><code>// 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 );
</code></pre>

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

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

<p><a href="https://i.sstatic.net/mhRdL.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/mhRdL.png" alt="Example of current situation"></a></p>

<p>However, when I change the normal of the back wall ever so slightly, the texture appears</p>

<p><a href="https://i.sstatic.net/IH1kH.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/IH1kH.png" alt="Situation with slightly changed normal"></a></p>

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

<p>I have been trying to figure this one out, but I am hitting a dead end.</p>

<raytracing><texture><uv-mapping><mapping>
How do I convert a hit on an infinite plane to UV coordinates for texturing in a Raytracer?
Czorio
# How do I convert a hit on an infinite plane to UV coordinates for texturing in a Raytracer?

(Asked by: username_0 on 2018-12-09)

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](https://i.sstatic.net/mhRdL.png)](https://i.sstatic.net/mhRdL.png)

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

[![Situation with slightly changed normal](https://i.sstatic.net/IH1kH.png)](https://i.sstatic.net/IH1kH.png)

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.

**Tags:** raytracing, texture, uv-mapping, mapping


---

## 1 answers

### Answer by username_1 on 2018-12-09. Score: 6 | Accepted answer

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);

```

> **Comments:**
> **username_0**: 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!  

---

