<p>I figured out the problem. It was not related to the ray / point transformation itself, but to a problem with the camera update after moving it (Up vector wasn't being computed properly).</p>

<p>I leave the answer in case someone have similar issues.</p>

CC BY-SA 3.0
2018-03-17T16:22:03.813Z
2018-03-17T16:22:03.813Z
Nadir
<p>Im writting a raytracer, for which I want to be able to test intersections with implicit surfaces (in my case spheres). Without applying any transformation it works great, but I would like to upgrade it to test intersections against non-uniform scaled spheres. For such purpose, I have computed the object's local to world matrix, as well as the world to local matrix.</p>

<p>During the intersection test, I first transform the ray origin and direction to the object local space:</p>

<pre><code>    Vector o = ray.getOrigin();
    Vector l = ray.getDirection();

#ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE
    o = worldToLocalMatrix * o;
    l = worldToLocalMatrix * Vector(l.x, l.y, l.z, 0.0f);
    l = l.Normalize();
#endif
</code></pre>

<p>I perform the test, compute the intersection point in object's local space and then transform it back to world space:</p>

<pre><code>Vector hitPoint(o + (l * distance));
        Vector hitNormal((hitPoint - center) / radius);
        hitNormal = hitNormal.Normalize();
#ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE
        hitPoint = localToWorldMatrix * hitPoint;
        hitNormal = localToWorldMatrix * Vector(hitNormal.x, hitNormal.y, hitNormal.z, 0.0f);
#endif
        hitNormal = hitNormal.Normalize();
</code></pre>

<p>If I run the raytracer, it works great:
<a href="https://i.sstatic.net/pwN09.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/pwN09.png" alt="enter image description here"></a></p>

<p>However, from some points of view (not all), I obtain wrong renders from the dielectric sphere (center in the above image) and the perfect specular (right in the above image), as well as one of the cubes:</p>

<p><a href="https://i.sstatic.net/dro4c.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/dro4c.png" alt="enter image description here"></a></p>

<p>If I just apply the affine transformations to the object's vertices and normals during start up(in the case of the sphere, I only apply translation since its an implicit surface), the render works flawlessly, so my guess its that the problem comes from the transformations applied to the ray.</p>

<p>To compute the local to world matrix:
<code>Model = rotation * translation * scale</code></p>

<p>To compute the world to local matrix:
<code>InvModel = inverse(scale) * inverse(translation) * inverse(rotation)</code></p>

<p>I would like to know if I'm applying the transformation to the ray as well as to the output hit properly</p>

CC BY-SA 3.0
2018-03-17T14:13:45.550Z
What's your question? It's unlikely that anyone else can debug your problem for you without a MCVE.
Dan Hulme
CC BY-SA 3.0
2018-03-17T14:21:16.210Z
@DanHulme I would like to know if the way im applying the transformation to the ray, as well as the hitpoint/normal is correct.
Nadir
CC BY-SA 3.0
2018-03-17T15:46:52.573Z
Probably not the only problem here but your normal transform is wrong: https://computergraphics.stackexchange.com/questions/1502
Olivier
CC BY-SA 3.0
2018-03-17T16:12:41.600Z
I tried using the transpose of the inverse for the normal, but it created black areas where it shouldn't, and the refraction was inverted. Since the normal is computed from sphere center to hitpoint, I also tried to compute it after transforming the hitpoint and  sphere center to world space, so I could avoid the normal transformation, but that didn't work either
Nadir
CC BY-SA 3.0
2018-03-17T16:18:54.963Z
Nevermind, I just figure it out. It was a problem related to the camera updating when moving, which wasnt computing the Up vector properly, and was causing the ray to be perturbed
Nadir
CC BY-SA 3.0
2018-03-18T10:25:16.050Z
Non-uniformly scaled spheres are ellipsoids. It's pretty easy to write down the equation of an ellipsoid and intersect it with a ray (just solving a quadratic). With that approach, you avoid all the confusing transformation stuff.
bubba
<raytracing><transformations><physically-based>
Ray tracing: transforming ray to object's local space for intersection test
Nadir
# Ray tracing: transforming ray to object's local space for intersection test

(Asked by: username_0 on 2018-03-17)

Im writting a raytracer, for which I want to be able to test intersections with implicit surfaces (in my case spheres). Without applying any transformation it works great, but I would like to upgrade it to test intersections against non-uniform scaled spheres. For such purpose, I have computed the object's local to world matrix, as well as the world to local matrix.

During the intersection test, I first transform the ray origin and direction to the object local space:

```
    Vector o = ray.getOrigin();
    Vector l = ray.getDirection();

#ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE
    o = worldToLocalMatrix * o;
    l = worldToLocalMatrix * Vector(l.x, l.y, l.z, 0.0f);
    l = l.Normalize();
#endif

```

I perform the test, compute the intersection point in object's local space and then transform it back to world space:

```
Vector hitPoint(o + (l * distance));
        Vector hitNormal((hitPoint - center) / radius);
        hitNormal = hitNormal.Normalize();
#ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE
        hitPoint = localToWorldMatrix * hitPoint;
        hitNormal = localToWorldMatrix * Vector(hitNormal.x, hitNormal.y, hitNormal.z, 0.0f);
#endif
        hitNormal = hitNormal.Normalize();

```

If I run the raytracer, it works great:
[![enter image description here](https://i.sstatic.net/pwN09.png)](https://i.sstatic.net/pwN09.png)

However, from some points of view (not all), I obtain wrong renders from the dielectric sphere (center in the above image) and the perfect specular (right in the above image), as well as one of the cubes:

[![enter image description here](https://i.sstatic.net/dro4c.png)](https://i.sstatic.net/dro4c.png)

If I just apply the affine transformations to the object's vertices and normals during start up(in the case of the sphere, I only apply translation since its an implicit surface), the render works flawlessly, so my guess its that the problem comes from the transformations applied to the ray.

To compute the local to world matrix:
`Model = rotation * translation * scale`

To compute the world to local matrix:
`InvModel = inverse(scale) * inverse(translation) * inverse(rotation)`

I would like to know if I'm applying the transformation to the ray as well as to the output hit properly

**Tags:** raytracing, transformations, physically-based

> **Comments:**
> **username_1**: What's your question? It's unlikely that anyone else can debug your problem for you without a MCVE.  
> **username_0**: @username_1 I would like to know if the way im applying the transformation to the ray, as well as the hitpoint/normal is correct.  
> **username_2**: Probably not the only problem here but your normal transform is wrong: https://computergraphics.stackexchange.com/questions/1502  
> **username_0**: I tried using the transpose of the inverse for the normal, but it created black areas where it shouldn't, and the refraction was inverted. Since the normal is computed from sphere center to hitpoint, I also tried to compute it after transforming the hitpoint and  sphere center to world space, so I could avoid the normal transformation, but that didn't work either  
> **username_0**: Nevermind, I just figure it out. It was a problem related to the camera updating when moving, which wasnt computing the Up vector properly, and was causing the ray to be perturbed  
> **username_3**: Non-uniformly scaled spheres are ellipsoids. It's pretty easy to write down the equation of an ellipsoid and intersect it with a ray (just solving a quadratic). With that approach, you avoid all the confusing transformation stuff.  

---

## 1 answers

### Answer by username_0 on 2018-03-17. Score: 1

I figured out the problem. It was not related to the ray / point transformation itself, but to a problem with the camera update after moving it (Up vector wasn't being computed properly).

I leave the answer in case someone have similar issues.


---

