6
\$\begingroup\$

Please note: Originally posted in stack overflow, redirected due to nature of problem.

I am making a procedural mesh game. I am trying to calculate the temperature for the player's current chunk by getting nearby temperature values and interpolating.

The way this works is, let's say we are at world space 95, 0, 65 (x,y,z). What I do is:

1) generate, using perlin noise, temperature values for every 20 squares (smartly generated to only do so to the 4 squares most relevant to us at any given time). We will get the points: 80, 0, 60 100, 0, 60 80, 0, 80 100, 0, 80

Each of these points is fed into a perlin noise generator and spits out a number. That number is the temperature.

So, in order to make the climate smoothly transition, I need to figure out how to get the distance each point weighted against its temperature so I can calculate the temperature of the space I am standing in.

If there is a name for this (there must be, I'm essentially sampling a gradient made by four points) and a way to do it, please just link that instead.

I tried taking the distance from my point to each point and multiplying that number against the temperature at that point, but I'm not sure if that's a correct first step, or what to do from there (just average the four resulting numbers?!).

\$\endgroup\$
1
  • 2
    \$\begingroup\$ If the temperature can vary in x, y, and z, then to get a smooth change everywhere you might need to sample all 8 grid points defining the corners of the cubic cell the player is in. That would be trilinear interpolation, rather than bilinear for the four corners of a square. I notice in your example though that y is always zero - is this a typical case / do you not need smooth temperature change along the y axis? \$\endgroup\$
    – DMGregory
    Commented Nov 29, 2015 at 15:23

3 Answers 3

1
\$\begingroup\$

The term you are looking for is bilinear interpolation.

If you have a grid of values, and you want to know what a value is when it's inbetween grid points, you can use bilinear interpolation to do this.

To do this you get the 4 grid points around the point you are looking at. You then interpolate the two values across the X axis, and then interpolate between those two values across the Y axis.

Here's an image showing how this works: enter image description here

The values at the corners are 7, 0, 3, 5 as labeled, and if you need to get the value where the relative coordinates inside of the grid cell are (0.2, 0.8), you can use linear interpolation to find the value for that point as 5.16.

It doesn't actually matter if you interpolate across the X axis and then the Y axis or the other way around, it comes up with the same value.

You can read more about bilinear interpolation here:

http://blog.demofox.org/2015/04/30/bilinear-filtering-bilinear-interpolation/

Note that bilinear interpolation is only ONE way to do this. There are many other ways to do this, but another popular method is bicubic interpolation. While linear interpolation interpolates values, bicubic interpolation interpolates both values as well as value slopes (the first derivative) so can be helpful in circumstances where you want smooth derivatives, like you might in the case you describe.

It works by doing cubic interpolation across one axis, and then the other, just like how bilinear interpolation works across one axis, and then the other.

For cubic interpolation (across a single axis) you need the closest 4 points on that axis, not just the closest 2 line linear needs.

The math is a bit more complex, but you can read more about the details here:

http://blog.demofox.org/2015/08/08/cubic-hermite-interpolation/

This link shows the differences when using a couple different types of 2d interpolations on pixels in an image, and has source code for each:

http://blog.demofox.org/2015/08/15/resizing-images-with-bicubic-interpolation/

EDIT:

I just noticed you are working in 3d not 2d. Everything I said still applies though. Interpolate the values across the X axis, then the Y axis, then the Z axis, and you'll have your result.

You'll need to interpolate 4 values across the X axis.

Then, you'll need to interpolate 2 values across those values, along the Y axis

Lastly, you'll interpolate across those 2 values along the Z axis to get your resulting value.

In 3d, the terminology is trilinear interpolation and tricubic interpolation.

\$\endgroup\$
1
\$\begingroup\$

You do not need to do anything special: Perlin noise is a gradient noise and is designed to give you an interpolated value at any point, not just at the square corners. Just use your Perlin noise generator at the player’s position.

\$\endgroup\$
2
  • \$\begingroup\$ Best answer by far. I'm leaving my info about bilinear/bicubic since it answers the title of the question, but you definitely have answered his specific question the best. \$\endgroup\$
    – Alan Wolfe
    Commented Dec 2, 2016 at 0:10
  • \$\begingroup\$ To add to this, you may want to consider using "simplex noise" instead (which was also made by Perlin, at a later date). In 3d a simplex has 4 points, so you'll be interpolating between 4 points, not 8, in the 3d case, which is less math / computation, so can be faster and more efficient. \$\endgroup\$
    – Alan Wolfe
    Commented Dec 2, 2016 at 1:05
0
\$\begingroup\$

What you will want is some form of linear interpolation, with weightings based on the distances to each square.

You could, if you wanted to be spiffy, model an actual thermal conduction coefficient.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Actually, since he wants to interpolate across 3 axes, it's called trilinear interpolation or trilinear filtering. \$\endgroup\$
    – Peethor
    Commented Dec 12, 2015 at 15:43
  • \$\begingroup\$ Right; I didn't realise that it had a specific name. \$\endgroup\$
    – Makcheese
    Commented Dec 12, 2015 at 16:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .