Creating Marble Like Textures Procedurally

I've been working a lot on my texture generation library. And it's starting to shape up nicely. It will take me a while for it to be on par with the likes of .werkkzeug or FXGen (let alone some of the stuff out there like ProFX).

One of the items I recently added to the library was a turbulence function. It basically takes an image as input, creates two perlin noise images, and uses them to determine the pixel offset between the output image and the input image... For example:

 

turns into this using the function:

 

The reason we use perlin noise instead of straight random numbers is we want the noise to be coherent. The smoother the noise, the more the final image is going to look like something coherent instead of random. And since marble, wood textures, etc. all need some semblance of coherency, we need it to act in this manner. Anyway, I'm sure that you're interested in the code:

 

Turbulence.zip (2.59 kb)

 The code has both the perlin noise class (and the interface that it derives from) and the turbulence function. So download the code, leave feedback, and as always happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 4/26/2008 at 10:20 AM
Tags: ,
Categories: Game Programming | Procedural Content
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Zoom, Rotate, and Procedural Content Generation

I figured I might as well show you the boring stuff I've been working on (well some of it). Specifically I'm going to show you the zoom and rotate capabilities I've added to my procedural texture generation and how to deal with wrapping.

Rotation 

Rotation is rather simple:

float NewX = (Cos(Angle) * (OriginalX - CenterX)) - (Sin(Angle) * (OriginalY - CenterY)) + CenterX;
float NewY = (Sin(Angle) * (OriginalX - CenterX)) + (Cos(Angle) * (OriginalY - CenterY)) + CenterY;

Doing this will rotate a single point around an axis defined by you (CenterX and CenterY). However if you do this with an image, you'll notice that this causes black spots to pop up at the corners of the image (basically where nothing exists on the original image). How can we fight this you ask? Simple, flip the image at key locations. Let me show you:

 

The image in the middle is the one we are trying to rotate. The images above and below the image are flipped around the x axis. The images to the left and right are flipped around the y axis.  So when you end up with a position off of the original image due to rotation, we end up on one of the four other images. And since it is only a small amount that should be visible of the other images, the fact that we flipped the image shouldn't be that noticeable. For instance:

 

is simply a rotation of:

 

Zoom

Adding zoom is just as simple:

float NewX=OldX*Coefficient;

float NewY=OldY*Coefficient;

The code is a bit simpler than rotation, but we run into the same issue. If you zoom out of an image, you'll see the original image get smaller and smaller in the upper left hand side of the image. In order to combat this, we use a similar technique:

 

The image in the upper left is the original. The image to the right is flipped along the y axis, the one below the original image is flipped along the x axis, and the one diagonal is flipped along both. However unlike the rotation, we have to deal with images past those. In order to make the images match up, we simply flip it each time we reach a new image. Each time we hit an image along the x axis that is not divisible by 2, we flip the original image around the y axis. Each time we hit an image along the y axis that is not divisible by 2, we flip the original image around the x axis. This leads to images that look like this:

 

This time around, the pattern becomes very noticeable. But on the bright side, we can zoom in and out of the image without seeing it surrounded by black.

Code

I know that I never explain these concepts in a manner that anyone but myself understands. I'm terrible at explaining anything, but that's why I give you code Tongue out:

 

RotateAndZoom.zip (1.79 kb)

The code works, but keep in mind that it uses a float array (was originally designed for height maps). So if you're going to use an image, you'll have to modify the code. Anyway, download the code, play with it, leave feedback, and as always happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 4/21/2008 at 2:39 PM
Tags: , ,
Categories: Game Programming | Procedural Content
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Fluvial Erosion

It's been a while since I posted anything about game programming. It's not because I've been lazy, but because most of what I've been doing wouldn't really interest the public at large. However, I did implement something rather interesting: Fluvial Erosion. If you're curious what that is, it's erosion caused by moving water (think rushing rivers, etc.). The version that I created is based off of the one presented by Ken Musgrave in his PHD Dissertation (page 58).

Now his version doesn't take into account pressure, evaporation, force of the water striking something, etc. In fact, it's about as basic as you can get. The basic premise is, you drop some water somewhere, it picks up some stuff, and it moves downhill. As it moves downhill, it either drops some of the stuff it picked up or picks up some more stuff... That's it. To be honest, there's not that much of a difference between this and the thermal erosion technique unless you carve out the rivers, gullies, etc. before using this approach. For example:

 

is a basic gradient, now let's assume that we drop some water in the middle. We might end up with this:

 

Not much of a change, but still somewhat noticeable. However did I mention that it took about 10,000 iterations to accomplish that? However each iteration is extremely fast. So if you were to say, run this in game for a river, it might get noticeable in a year or so (definitely something to think about when you create that next gen MMO). Anyway, the basic code for this is here:

 

FluvialErosion.zip (1.37 kb)

Not the best implementation in the world (as I'm sure there are a couple of bugs) but it does the job. So download it, leave feedback, etc. and as always happy coding.

kick it on DotNetKicks.com   Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkListEmail

Posted by: James Craig
Posted on: 4/18/2008 at 3:05 PM
Tags: ,
Categories: Game Programming | Procedural Content
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed