Fast perlin noise heightmap function added to code archives.

Blitz3D Forums/Blitz3D Programming/Fast perlin noise heightmap function added to code archives.

sswift(Posted 2003) [#1]
Right here.


Koriolis(Posted 2003) [#2]
Cool. You'll never stop to give us valuable code, will you ? :)


sswift(Posted 2003) [#3]
I just updated the function...

I noticed unsightly diamond artifacts in the resulting perlin noise caused by the bilinear filtering algorithm.

I looked up bicubic filtering and discovered that was a lot more complicated than I thought. It turns out that bilinear filtering when scaling an image up is really the right way to do things. I thought it was just a crappy approximation, but it's not. Bicubic is the clever trick.

So with this knowledge in hand, and not wanting to attempt to implement bicubic, I noticed that another fellow's perlin noise function used something called "cosine weighting". I didn't look at his code to see what he was doing cause it was too much of a bother to figure out, so I just implemented what I thought cosine weighting meant, and I guess I was right because the results look really nice.

Basically what I did was use a cosine to modify the location of the subpixel sample, on each axis during the bilienar filtering.

In layman's terms... If you take a cosine, and go from 0..180 degrees, the cosine goes in a nice sine curve from 1 down through 0, to -1.

Now normally, when you'ree bilinear filtering you'll step across the tile, and at each location figure out where you are 0..1 between the two pixels, and then multiply one of them by 1.0-L#, and the other by L#, and add them, and that gives you a weighted average.

Well what I did with the cosine was instead of simply using L#, I took L# and divided it by 180. This gave me an angle 0..180 which I coudl then input into my cosine. Once I did that, my cosine output a value between 1 and -1. But for my average I needed a vlaue between 0 and 1, so I added 1 to the value, and divided by 2. This gave me the value between 1 and 0 which I needed.

Now I had a value that went between 0 and 1, but it didn't move linearly between them at a constant rate... Instead it moved along slowly at first, then approaches 0.5 quickly, and then speeds away from it, and then slows down and approaches 1.0.

This basically pushes the colors of the pixels at the four corners towards the center of the square, making the area which is the average of the colors smaller. And it makes the areas around each pixel round instead of diamond shape.

Which got rid of those diamond artifacts.

And now we both know what cosine weighted averages are, unless I lost you somwhere back near subpixel sampling!


sswift(Posted 2003) [#4]
"You'll never stop to give us valuable code, will you ? :)"

Only if I switch back to Dark Basic! :-)


ashmantle(Posted 2003) [#5]
heh.. like that will ever happen ;) (well.. maybe after Patch 27?)


Difference(Posted 2003) [#6]
Very nice, results looks very good. Thanks for sharing it.

Are planning on doing a version that makes tileable pictures?


sswift(Posted 2003) [#7]
Seamless heightmaps? I don't know why you'd want such a thing, other than for some kind of texture creation program.

Doing that is trivial though.

All you need to do is when the noisemap is generated each pass, copy the pixels in the left colum to the right column, and copy the pixels in the top row to the bottom row.

That's all you need to do to make it seamless.


sswift(Posted 2003) [#8]
Hm.. I rendered two heightmaps with the same random number seed and one with the cosine weighting and the other with plain bilinear filtering, and man you would not beleive the difference in quality. The cosine one has higher contrast, (which means more height variation) as well as more naturally shaped structures, (round hills vs diamond shaped ones) and all these tiny details that were just blirred out before become visible. I'm really surprised that this cosine weighting improved the image quality that much.

I wonder if cosine weighting would be good to use when scaling regular images up?


Anthony Flack(Posted 2003) [#9]
Hey, sswift, not only do you contribute valuable routines, but you've just taught me something cool. Again. The way you explained it makes it crystal clear, and now that I have grasped the concept I can immediately see the coolness of it. You're one smart cookie. And I'm fractionally more clued up than I was when you found me. thanks again.


Difference(Posted 2003) [#10]
Yes, the seamless thing was for texture creation. I also heard some people talking about tilable terrains.

Thanks for explaining how to implement it.


Rob Farley(Posted 2003) [#11]
Heh, I've just done one of these too! Going to have to compare results. Mine uses cosine interpolation too.