We've come a long way. Starting with a simple dungeon all the way up to the noise functions. Having made it this far is an accomplishment. It's time to move onto bigger and better things though. All of our past posts have been dealing with 2-dimensional content. Today we are going to start 3D, specifically 3D planets ( A.K.A. normal planets ).
Procedural planets are a pretty popular topic currently. There are many video games like No Man's Sky ( We are going to talk in more detail about this game in the next post ), and the impressively realistic Space Engine among many others that generate these procedural planets. So let's first talk a little bit about some ways it's done first.
As you have previously seen, there are many ways to accomplish a task with procedural content generation, this is no exception. One way to generate procedural is to actually start with a cube and use a noise function like Perlin or Worley and adjust the points on the cube based on those height values. From there the cube is then projected to a sphere and you have a planet with terrain!
This is not how we are going to do ours though. We are going to do something completely different in fact. While doing some research I stumbled upon one persons interesting idea on procedural planets. It was relatively simple to implement however he had not done it. So I decided to implement it for this post and see how good the generated planets look.
The basic idea is as follows. You first generate a plane with a random rotation around the x, y, and z-axis. You then get every vertex on your planets surface and dot product it with the planes normal vector. If the dot product is greater than zero you move the point in a small amount, if the dot product is less than zero you move it out a small out, and if that dot product is zero, you leave it alone. This is done over a number of iterations with a random plane each time and it will generate peaks and valleys due to the random moving in and out of points. Pretty clever, so let's implement it.
As you can see, there's quite a bit of new stuff here that we have never seen before. That is because this is part of a bigger project. There's a considerable amount of code that is rendering the planet, moving the camera, and things like that. We're not gonna talk about that cause that's a different blog. We're interested in the code above.
As you can see we first make a normal vector that is the planes normal. This is random and each value is between -1 and 1. We create a scale value and determine how many iterations we want to do. We loop through the iterations and loop through each vertice with each iteration doing the dot product each time and moving the points by a scale value. So, let's run it and see how it turns out.
First, this is what our "planet" looks like before we did anything to it. I applied a random texture I had readily available. At this point it's a perfect sphere so all is good.
Next, I ran it over 1 iteration just to test if this idea would even work at all. It did! It created a weirdly shaped planet by moving the bottom inwards and the top out. Great! Let's run it over a larger number of iterations.
Hmm... Interesting. This was run over 100 iterations. You can clearly see the planet was misshaped and now has a series of peaks and valleys. If you look at pictures of earth from space though you can't see the difference in elevation, it looks perfectly round and this doesn't! That is because this is on a small scale. In order to achieve that effect I would have to make the scale factor incredibly small and the planet incredibly large with a staggering number of vertices and I don't have the time for that.
Because of this, I would say the "planet" looks more like an asteroid. So perhaps our method needs to be slightly different. Maybe we will try a new method in the future. But for now, we have a starting place. We rendered some planets and we made them not perfectly spherical.
As usual, thanks for reading. Hopefully we get a better result next time. If you want to see the full source code go here. I have added all necessary code in the Prodedural_Planets folder so you can run it if you want. The code in this post is located in mesh.cpp.
No comments:
Post a Comment