4
$\begingroup$

If you have values on a grid and you want to find the value of a point within one of the cells, you can use techniques like bilinear or bicubic interpolation to get the data at that point.

What technique(s) would be used if the data on the grid was a vector (a surface normal specifically)?

I know that quaternions are good for slerping, which I think could be good in this case to do a "bilinear slerp", but quaternions require basis vectors that represent an orientation, not just a single vector.

Also, I'm not sure how you'd use quaternions to apply something like bicubic interpolation.

What methods would be good in this case, to interpolate vectors on a grid?

$\endgroup$
  • $\begingroup$ Slerp is a possibility for normals. It stands for "spherical lerp"—unit vectors lie on a sphere as much as unit quaternions do. $\endgroup$ – John Calsbeek Feb 19 '16 at 7:08
  • 1
    $\begingroup$ I've found out that nlerp is a decent method: just interpolate your components and re-normalize. I can do a bicubic version of this by doing each component individually. Found some decent links too: keithmaggio.wordpress.com/2011/02/15/… and number-none.com/product/… . $\endgroup$ – Alan Wolfe Feb 19 '16 at 14:50
  • 1
    $\begingroup$ If you know your grid vectors don't vary more than, say, 120 degrees from grid point to grid point (i.e. trying to avoid problems with "which way do you interpolate), why wouldn't bicubic interpolation with renormalisation be "good enough"? $\endgroup$ – Simon F Feb 19 '16 at 14:55
5
$\begingroup$

I did some research and found the answer I was looking for. The three most common ways to interpolate vectors are:

  1. Slerp - short for "spherical interpolation", this is the most correct way, but is also the costliest. In practice you likely do not need the precision.
  2. lerp - short for "linear interpolation", you just do a regular linear interpolation between the vectors and use that as a result.
  3. nlerp - short for "normalized linear interpolation" you just normalize the result of a lerp. Useful if you need your interpolated vector to be a normalized vector.

In practice, lerp/nlerp are pretty good at getting a pretty close interpolated direction so long as the angle they are interpolating between is sufficiently small (say, 90 degrees, or 120 like Simon mentions in his comment), and nlerp is of course good at keeping the right length, if you need a normalized vector. If you want to preserve the length while interpolating between non normalized vectors, you could always interpolate the length and direction separately.

Here is an example of the three interpolations on a large angle. Dark grey = start vector, light grey = end vector. Green = slerp, blue = lerp, orange = nlerp.
enter image description here

Here is an example of a medium sized angle (~90 degrees) interpolating the same time t between the angles:
enter image description here

Lastly, here's a smaller angle (~35 degrees). You can see that the results of lerp / nlerp are more accurate as the angle between the interpolated vectors gets smaller.
enter image description here

If you do lerp or nlerp, you can definitely do both bilinear as well as bicubic interpolation.

Using slerp, you can do bilinear interpolation, but I'm not sure how bicubic would translate.

I generated these images by taking screenshots from an interactive shadertoy demo I made to demonstrate these differences. You can see that shadertoy here:
https://www.shadertoy.com/view/4sV3zt

$\endgroup$
  • $\begingroup$ Thanks for taking the time, on both the answer and the ShaderToy example! $\endgroup$ – Rotem Feb 22 '16 at 14:16
  • $\begingroup$ Lerp and nlerp seem “good enough” for angles <90°, but when you start getting higher (especially around 180°), the inaccuracies of lerp/nlerp become extremely pronounced. I modified your ShaderToy example to have the vectors be 178.2° (180° * 0.99) apart from each other and the lerp/nlerp results are garbage: shadertoy.com/view/4sGGWd If you can guarantee that the angle delta will be <90° lerp/nlerp may be a fair optimization; if not, I think using slerp in combination with heavy memoization or a pre-computed lookup table is a safer and fast-enough way to go. $\endgroup$ – Slipp D. Thompson Mar 2 '16 at 20:23
  • $\begingroup$ I think you missed the fact that you can click the mouse to change the vector angles! and yeah, it gets real bad at larger angles. You can even see that in the top image in my answer! $\endgroup$ – Alan Wolfe Mar 2 '16 at 20:40
  • $\begingroup$ @AlanWolfe: Side-note: I can write up an answer than pre-computes the slerp results into a texture and looks-up the values at runtime, if you're interested. Given that the color value is the output normal, and if we can assume both lookup vectors are normal-or-nearly-normal-length, I believe the lookup table can be reduced to only plausible inputs, without covering the whole input space (4-dimensional, 2 for each input vector) and without resorting to using vector angles as inputs (2-dimensional, but still incurs the atan2 cost). $\endgroup$ – Slipp D. Thompson Mar 2 '16 at 20:40
  • $\begingroup$ @AlanWolfe Ha, yah, I totally did. You're one step ahead of me! Deleting my shadertoy clone (link above is now dead). $\endgroup$ – Slipp D. Thompson Mar 2 '16 at 20:41

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.