Monday, December 21, 2009

GPU Perlin Noise

I updated my DirectX before starting and somehow my MDX project became all liney, like this:

Uhhh

Because of this, and because most of the online samples I find to plagiarize be inspired by are usually in XNA I decided to convert. Unfortunately there’s no automatic conversion tool so I had to open a new project, add my old files and try to fix up the errors. Some things were annoying, like the lack of absolute mouse movement and having to load a font from a file (size is fixed in the file) but overall the classes are better named and organised. Here’s my first shader on the planet in XNA, stripes:

stripey

So after a quick crash course on shaders, I found Perlin had published HLSL code for Improved Perlin noise in GPU Gems 2 – all of which is free online! I had real trouble getting it going however, every texture I generated was blank, and I didn’t know enough about HLSL to figure it out. There seemed to be a tutorial on ziggyware but it seems ziggyware’s been under attack from hackers so I couldn’t get it. I tried out some other projects like Drilian’s but again the XNA version I made the noise didn’t work. Eventually I found a post where someone had similar problems, which led me to the Google cache of the XNA GPU Perlin noise tutorial – by Patrick of recreationstudios (he’s made some amazing progress since I deserted this project 2 years ago). All I needed to do was initialise the textures all the noise functions use. Perlin had functions to do this in HLSL, but I hadn’t a clue how to call them, supposedly you can’t in XNA so I moved the HLSL code to C# then create the textures on the CPU and set the textures on the GPU. Patrick’s tutorial explains this much better (prize-winningly better apparently) so I won’t go into details.

So here are some screens of different types of Perlin noise on the planet:

Noise

NoiseRidgedMF

In these shots the noise is being calculated per-pixel each frame based on the geometry. Surprisingly, getting closer to the planet so the level of detail is higher (the 4 child patches are drawn instead of the parent patch) didn’t change the surface visibly. This had to do with the fact that there wasn’t much geometry difference between the parents and the children, when I changed the patch size from 33x33 to 5x5 there was definite popping in the textures.

Here’s a video of flying about a bit:

Update: shading every frame means I can animate!

3 comments:

Patrick said...

The animated noise on the planet looks sweet!

I'm really glad my tutorial could be of use. Interesting fact - that was my post on the XNA forums as well (I'm GlitchEnzo).

I didn't realize that Ziggyware was down, so I'm worry you had to work so hard to find the tutorial. For future reference, or anyone else who needs it, I do have a copy of the tutorial and all of the files on my website.

You can find them all here:
http://re-creationstudios.com/shared/PerlinNoiseGPU/

If you have any questions, feel free to ask.

John Leonard said...

Cheers Patrick, the tutorial was a lifesaver - I couldn't work out how to init the textures with the functions in the shader (I'm a real shader novice). The animations are soooo easy to do & visually impressive - shame the fps suffers so much. I spent loads of last night making a Jupiter looking planet, it looked awesome, I'll up a vid next post.

You've done tons since I was last talking to ya, that deferred shading looks amazing I'll have to look into how to do that! So yeah, I'll have plenty of questions for ya! :)

Unknown said...

Patrick your tutorial just saved me lots of time!! Thanks www.xortron.net