Posts In: perlin noise

Procedural Texture

I'm back to playing with texture functions for a bit, mainly because I'm testing a new CPU-side texture generation method that I just implemented to make direct editing/creation of textures on the CPU really painless. The application that creates this texture is < 40 lines of code (no, that's not Python; it's c++!). Yes, it's black magic. Intuitive, scary, black magic. Same old Perlin nonsense, this time with intentional banding! It looks rather nice. Hence the post.

3D Perlin Noise

With the power of a working isosurface extraction algorithm, I decided, quite naturally, to test the capabilities of marching cubes on the 3-dimensional analogue of my favorite noise function - perlin noise.

Coding a perlin noise function to work in tandem with the marching cubes algorithm was simply a matter of transferring the 3D perlin noise function that I had already written in HLSL over to equivalent CPU instructions.

The results, though quite intriguing to look at, aren't particularly beautiful.

Unfortunately, 3D perlin noise does not seem to be feasible for real-time application. Generating one or two meshes that use 3D perlin noise may be acceptable, but making heavy use of the function simply isn't feasible if loading times are to be kept reasonable. It's slow. Really slow. Perlin noise is already a computationally-expensive function, and the fact that I'm now running a 3D analogue of it (which is, by nature, more expensive than 2D) on the CPU rather than the GPU makes the problem intractable. The CPU simply isn't capable of crunching the math fast enough.

In the long run, I'm going to look into alternatives to 3D perlin noise. The function would be a great asset for a new reality, but it's not practical for real-time application at the moment - at least on the CPU. In the future, I'll try to look into DirectX 10's stream out, as I know that it can be used to perform marching cubes on the GPU (probably in a ludicrously small fraction of the time that it takes the CPU).

Procedural Sunset

After implementing several new features in DirectX, including a bloom effect and a skydome primitive, I experimented with making skies that could pass as acceptable. Though not by any means blown away by the appearance of my procedural clouds (let's face it, when it comes right down to it, perlin noise doesn't look anything like real volumetric clouds), I was quite happy with the overall effect created by the skydome, the bloom shader, and a sunset-style fog.

The result:

Note that the cloud shader actually consists of a turbulent perlin noise, which gives the clouds a slightly nicer appearance than simple perlin noise would allow. Interestingly, the seed value of the noise can be animated, along with scrolling of the texture coordinate offset, to produce the illusion of moving, ever-changing clouds. Unfortunately, the technique is quite expensive, especially for high-resolution cloud maps. However, with the rapidly-expanding power of graphics cards, it may be viable to animate a full, dynamic, 1024 res cloudmap in at smooth framerates in the very near future.

Multifractals: Beautiful Terrains

Here it is...a rendering of a terrain using a multifractal heightmap. I think the beauty of the terrain speaks for itself!

Notice the juxtaposition of the extremely flat region near the camera with the mountains in the background. Such extreme features can only happen in multifractals!

Perlin Noise Shader

I did it!!

After hours and hours of reading tutorials on HLSL coding, I finally managed to write a perlin noise shader. The result? Unbelievable speed. At least 100x faster than the CPU-based implementation I coded a few months ago. It can easily display a new 512 by 512 heightmap at 60 FPS. Yes, that's 60 unique heightmaps in one second.

With this kind of raw power now available to me for procedural content generation, I know that great things lie ahead in terms of my work with virtual worlds.

For reference (since I lost the old one and had to rewrite from scratch), here's the noise function I used:

float Noise2D(float x,float y)
float a = acos(cos(((x+SEED*9939.0134)*(x+546.1976)+1)/(y*(y+48.9995)+149.7913)) + sin(x+y/71.0013))/PI;
float b = sin(a*10000+SEED) + 1;
return b*.5;

An Original, Realistic Algorithm for Terrain Erosion

February 23, 2010 Algorithmic Art 0 Comments

Yes, another non-music digression. I can't stand not to write about this though, considering the fact that I've had a serious breakthrough today with a new algorithm.

Here's the problem: erosion algorithms tend to produce a sort of homogeneous soup of terrain without recreating some of the more true-to-life effects such as fractal coastlines and such.  The solution? A terrain density map.  As far as I know, this is a completely original algorithm.  I've seen nothing like it in the literature, so I'm quite excited about having invented it.  The initial test runs also produced exciting results!

Here's the basic concept: real terrains are not homogeneous.  Not all dirt is created equal. So, along with a 2-dimensional array representing the heightmap of a terrain, we should also create an equally-sized 2-dimensional array representing the density (or integrity, if the term is preferred) of the terrain at each given point. The density array can be filled with a low-octave perlin noise function (I found two to three octaves to give optimal results, with a persistence of between 1.5 and 2).

Now, we perform an erosion algorithm as usual, except that we use the density of the terrain at each point as the threshold value for erosion. That is, if the amount of potential erosion at a point is less than the density of the terrain at that point, then the point will resist erosion. Ideally, this algorithm erodes terrain in a more coherent, less uniform way than typical thermal erosion algorithms. For example, coasts display some fractal dimension now since some areas of the terrain erode more easily than others.

A sample heightmap using the new algorithm:

The difference is most notable around the rivers, where the coasts clearly display some fractal coherence absent in thermal erosion algorithms. Notice that "noise" of the coastlines is clearly more coherent than single-octave noise, thanks to the perlin-based density map.

I am still trying to work out how to make the features appear larger (that is, make the coast even more jagged), since the heightmap, although nice, isn't drastically different from previous ones. I am quite confident, however, that there's a lot of potential in this new density erosion algorithm. Who knows, maybe this will be the future choice algorithm for procedural terrain erosion!

Techniques for Heightmap Synthesis: II

February 14, 2010 Algorithmic Art 0 Comments

I have made a great deal of progress today in my work with virtual terrains!

In the last post I mentioned bucket fill algorithms and how they could contribute to realism by creating isocontours on the heightmap. I have successfully written and applied my own tolerance bucket fill algorithm. Unlike most such algorithms, however, my version actually preserves a set amount of the original surface variation, so as not to create a completely flat contour - which, of course, would be unrealistic.

I have also written a perlin noise generator to give variation to the heightmaps. Perlin noise is simply a linear combination of noise functions with varied frequencies and amplitudes. In practice, perlin noise generators often use a coherent noise function, such as a high-frequency sinusoid. I chose, however, to use only a simple rand() function. By mapping each point on the heightmap to a point on the (increasingly large) noise maps and performing 2-dimensional linear interpolation, one can achieve the desired effect without having to use trigonometric functions.

Now, using an additive combination of Brownian random deposition walks, bucket fills, perlin noise, and softening, I am able to create much more realistic terrains.

Below are a few sample heightmaps created with the aforementioned methods:

A quick summary of what's going on in these heightmaps:

  • Random deposition walks create long, winding rivers and mountain ranges
  • Bucket fills level out parts of the terrain to create isocontours, which give the appearance of defined features like plateaus
  • Perlin noise randomizes the space in between features with coherent noise
  • Softening passes remove rough spots created by deposition and bucket fills