Wednesday, November 18, 2015

Perlin Noise

Welcome back! Last time we discussed the Diamond-Square algorithm. While that algorithm works great for certain cases, it had its drawbacks that we discussed last post. Instead of fixing those we're gonna just implement a different way to get similar results. That way is Perlin Noise!

So what is Perlin Noise? Well similarly to Diamond-Square, it's a way of generating random height-maps that can be used for a number of things. Games are generally a place they are used commonly to create random terrains. It is very simple to implement and produces much better looking results than Diamond-Square as it does not have the same artifacts. The biggest drawback to Perlin Noise is that it is slightly slower than Diamond Square and it can only generate squares. Both of these can be worked around though so lets dive into the code.



Above we can see the constructor for our Perlin Noise class. We haven't looked at most of the constructors before but this one does more than most. In this one we fill a vector with random values. These random values are dependent on our seed and act as the "gradient" for the rest of the algorithm which will be talked about more later on.



Here we have our perlin method. This is where the majority of our calculations and code is. There is a lot of stuff going on here so I will cover the basics. If you are very interested in each low level idea, Ken Perlin wrote an entire paper about Perlin Noise you can read. So, carrying on. First we take the floor of our values and bitwise and them with 255 ( Read here if you don't know what bitwise operations are ). We then subtract these values from the floor of themselves. Then we see another method we haven't seen yet, fade. Let's look at fade.



Here we can see all of the methods we haven't seen yet. Fade and grad are actually unique in that every implementation of Perlin Noise is supposed to/should use the same equation made by Ken. You can see it is just a simple math equation where we multiply and add some values. So carrying on, we can next see where our gradient values come on. These are chosen based from our x, y, and z, and the subsequent variables that came from them. We then see the grad method actually used. Here a series of bitwise operations change the values. These help insure randomness. They are then linear interpreted ( lerp ) with each other in our lerp method. This is just a stand linear interpolation, nothing fancy. This is done multiple times over every point. So how do we actually use this?



Above is our to_png method. We need some visual representation to output this to to see our results and that is how we do it. So lets run it and see what it looks like.
Wow, look at that! It looks random! And every time we run it it will be random. But wait... What is the commented code? Well with Perlin Noise we can easily modify the produced values to create something... different. Let's uncomment that code and run it and see what happens!
Wow! Look at that! That commented code works well for producing a wood-like texture. Pretty nifty. Playing around more can create different effects but I will let you explore them yourselves. Hope you enjoyed this and learned something new. As usual, see the full code here.

Sunday, November 15, 2015

Diamond Square

Last time we talked about the Midpoint Displacement algorithm in preparation for the Diamond Square algorithm. Dimond Square is basically a 2D version of Midpoint Displacement. It has lots of use in modern video games due to its speed and ease of implementation. So let's get started to see how it actually works.


Wikipedia has a helpful image to help easily understand the algorithm. First four corners are selected and their height values are remembered. Those values are averaged and given a random offset value. The center of those four is now the new corner. This is the diamond step. The square step is next. The middle is used as a reference and each point out from it is set to a random value and the average of the four corners. This is repeated multiple times. 

In the code below we can see the implementation of the "generate" method. This method is where the bulk of the work for Diamond Square is done. It loops over the grid a certain number of times, each time doing a "diamond' step and a "square" step as discussed above.

Then below we can see the implementation of the actual diamond_step and square_step methods. These do as discussed in the description above.

The last bit we have to talk about is the sample method. This is a clever method that uses bit operations to get locations on the map. Because of how it works it allows the map to wrap around itself and generate maps that have borders that will be seamless. We can see the actual implementation below.

Now that we see how it works, we can see the result!
This is an example output. We can see the high areas are lighter than low areas. This has a fault though which is discussed below.

While this algorithm has advantages, it also comes with some downfalls. One of the notable downfalls that affects many when using this algorithm is that it has a tendency to generate ridges in lines. So many times there will be a set of ridge peaks or valleys at very similar locations. There are ways around this but those are out of the scope of this post. Another downfall is that the map has to be a size of 2^n + 1. This is rarely a problem but can be if you need a certain sized map. The simplicity of this algorithm is what makes it so powerful and why these downfalls are rarely an actual problem.

Thats the basics with Diamond Square. It's a simple implementation and generates random results. As usual hope you learned something and heres the full code.

Wednesday, November 4, 2015

Midpoint Displacement

Up until now all of our programs have been printing grids to console. These were cool to look at but were often only useful for a very specialized purpose. Because of this were are going to do something very different. We are going to write our own Midpoint Displacement algorithm. Midpoint Displacement is a form of the Diamond-Square algorithm ( another algorithm we will be covering later on ). These two algorithms are very similar the main difference being Midpoint-Displacement outputs a line while Diamond-Square outputs a grid. However, to better understand Diamond-Square we later on we are starting simple with Midpoint-Displacement. So let's get started!

Midpoint-Displacement is an extremely simple algorithm ( I wrote a Java version back in high school its so simple ) but it creates unique and interesting outputs every time we run it. The algorithm works as follows. First, two endpoints are created. These will be used as anchors. A midpoint is then found between the two points and it offset by a random number based on a "roughness" value. The algorithm is then run again doing the same thing. Finding the middle between each point and raising or lowering the point based on the "roughness." The idea is simple so let's see what it looks like in code.

Extremely straightforward. The method calls itself each loop around and makes sure that it is only doing the number of points that there should be. We can see there are two methods that we use that are not in the code so we can look at those briefly below.

The "middle" method is just your run of the mill midpoint formula that you learned in elementary school. Then with the "displace" method we can see that we keep the x-value the same and modify the y-value based on it's current value plus a random number in between the negative roughness and positive roughness.

In order to see how what this outputs, I wrote a small method that plots the x and y values on a black image. So when we run the program, we might expect to see something like this.
Or something like this.
We can see that the Midpoint-Displacement algorithm generates ridges and valleys. This has some practical use in real games too! 
I lot of people probably remember playing that game ( or something similar ). It used an algorithm similar to Midpoint-Displacement to create its random and interesting terrains. 

We've got a basic understanding of Midpoint-Displacement now so we can next talk about the Diamond-Square algorithm! This algorithm also has a lot of use in real life games. As usual, hope you learned something and you can see the source code here.