How to use a heightmap data for motion?

Hi, I am looking reference material on how to use a heightmap or noise background image to move particles in 2D, so the particles move to the white areas of the image.

Any links, tutorials and reference material will be much appreciated



bunch of steps:

  1. translate particle position to a 2d pixel position on the heightmap.

  2. calculate a 2d gradient vector (direction) based on the pixel values surrounding the particle’s position, moving from darkest to lightest. how you do this is up to you. experiment! :slight_smile:

  3. apply the 2d gradient vector to your particle as either a velocity (easier math, less interesting animation) or an acceleration (harder math, more interesting animation). use kinematic equations: x = x + timestep*velocity and perhaps beforehand velocity = velocity + timestep*acceleration.

good luck!

there’s an example that uses the frame difference in a video stream as an heightmap that controls a vectorfield that controls particles; you can find it inside-this-archive

Hi, thanks for the comments, I found the following algorithm, but I am stuck in step 4, I am a novice in programming, and so far I don’t understand is how to build the kernel, so any ideas, pseudocode, explanation, will be much appreciated.

1->Generate Perlin in black and white

2->Generate text, place in center

3->Imagine the whiteness to be a height value. Darker == lower, ligher == higher.

4->Convert the bitmap into a slope / normal map. Follow this process :
1.Convolution with a 3x3 kernel, y-1 and y+1 as 1,div by 2 bias 127, copy to red channel
2.Convolution with a 3x3 kernel x-1 and x+1 as 1, div by 2, bias 127, copy to blue channel

Now red and blue are converted into slope values for every pixel. Use this slope value to accelerate or decelerate your particles.

Use a linked list with small datatypes for your particles. Read out from the slope map to move them, add some elastics…et voila.

A position on your normal / slope map has a color. This color encodes x in red and y in green. If you read the green value, you divide it’s value by 128 and -1 one that value.

That will give you a value between -1 and +1. Depending on the speed you want to add to the particles, you multiply that value and add it to the velocity of the particle. Same goes for the red channel.

Thanks again!

you’re right, that’s not a very clear description.

what they mean is to use a particular 3x3 kernel for convolution. convolution gives you a single number output for each pixel. basically a normal 3x3 gaussian kernel gives you an average of the 8 pixels and the 9th central pixel in a 3x3 block. but in this case we need to use a different kernel. you can try a couple but i think the sobel kernels are best here:

then you take this value, divide it by 2 and subtract 127, this gives you a number between -127 and 127 for the vertical gradient. then you do it again for the horizontal gradient. the two values together give you a 2d gradient vector.

Hi damian, that is an awesome article, now I get to understand a bit more, I will try using that kernel and post any progress later


I manage to get it working, now I have a gradient vector at every pixel, and here is when I got stuck, from what I understand so far, I can use the gradient vector to accellerate the particles, and even get the orientation of the slope.

So I am trying to get the pixel data from the particle location, the get that value from the pixel array, normalize and equal to particle.acceleration… FAIL

Not sure how to use the data, any ideas?


Got it! it is all working fine

Thanks a lot