Search code examples
graphicsvectorlinear-algebraraytracing

RayTracing: When to Normalize a vector?


I am rewriting my ray tracer and just trying to better understand certain aspects of it.

I seem to have down pat the issue regarding normals and how you should multiply them by the inverse of the transpose of a transformation matrix.

What I'm confused about is when I should be normalizing my direction vectors?

I'm following a certain book and sometimes it'll explicitly state to Normalize my vector and other cases it doesn't and I find out that I needed to.

Normalized vector is in the same direction with just unit length 1? So I'm unclear when it is necessary?

Thanks


Solution

  • tl;dr: Normalized vectors simplify your math. They also reduce the number of very hard to diagnose visual artifacts in your images.

    Normalized vector is in the same direction with just unit length 1? So I'm unclear when it is necessary?

    You almost always want all vectors in a ray tracer to be normalized.

    The simplest example is that of the intersection test: where does a bouncing ray hit another object.

    Consider a ray where:

    p(t) = p_0 + v * t
    

    In this case, a point anywhere along that ray p(t) is defined as an offset from the original point p_0 and an offset along a particular direction v. For every increment of parameter t, the resulting p(t) will move another increment of length equal to the length of the vector v.

    Remember, you know p_0 and v. When you are trying to find the point where this ray next hits another object, you have to solve for that t. It is obviously more convenient, if not always obviously necessary, to use normalized vector vs in that representation.

    However, that same vector v is used in lighting calculations. Imagine that we have another direction vector u that points towards a lighting source. For the purpose of a very simple shading model, we can define the light at a particular point to be the dot product between those two vectors:

    L(p) = v * u
    

    Admittedly, this is a very uninteresting reflection model but it captures the high points of the discussion. A spot on a surface is bright if reflection points towards the light and dim if not.

    Now, remember that another way of writing this dot product is the product of the magnitudes of the vectors times the cosine of the angle between them:

    L(p) = ||v|| ||u|| cos(theta)
    

    If u and v are of unit length (normalized), then the equation will evaluate to be proportional to the angle between the two vectors. However, if v is not of unit length, say because you didn't bother to normalize after reflecting the vector in the ray model above, now your lighting model has a problem. Spots on the surface using a larger v will be much brighter than spots that do not.