Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

Voxel world engine - Proceduralize all of the things!

Sign in to follow this  
CC Ricers


Here's some more progress on the SeedWorld voxel engine. Last week has been mostly occupied with tweaking stuff- tweaking noise outputs, heightmap parameters, and color gradients. It's been a ton of trial and error to get a landscape that I was happy with, but I think I needed a new perspective in order to not burn myself out on it.

I added some basic voxel shadow casting code. All it does is, for every X, Z coordinate on the surface, start from the topmost voxel and move down, checking if a voxel is solid or empty. The first solid voxel blocks sunlight and the rest of the voxels are darkened. It's simple, but with some shadow smoothing the effect will look even better.

I know how to make a landscape that can alternate between long, mostly flat plains and rolling hills and mountain ranges. But the more I looked and moved around it, the more it looked the same. It looked boring. But then I remembered that the environment was far from complete. There are no trees, boulders or other clutter filling up the place. So I decided to start adding trees. The first step I took was making a function that can produce a voxel sphere. These were the leaves for the tree. Then I added a square pillar for the stump.


Now at least I'm getting somewhere. Here are a bunch of spheres casting shadows on the ground.


Enjoy that green while it lasts, because I soon removed it. This helped me just look at the details of the landscape and not think of how repetitive it looks with everything being grass green. All the code for coloring voxels was hard-coded into the Chunk class, and this had to be moved sooner or later. Voxel color of natural features will probably be controlled by Biome classes or something similar.

So for now, everything is colored white with AO and directional lighting. Here are some screenshots of Grayscale Land.



The only condition for the tree-generation code is that they are to be placed where the elevation is lower than 80. But trees don't naturally occur in such an orderly fashion, so it's time to mix it up. My tree generation code consists of finding a surface voxel to "plant" it, and then use some loops to place cubes near the bottom for the trunk. For the leaves, a function to determine whether a location is inside a sphere is used. Leaf cubes are placed anywhere it's in the sphere.

The placement now needs to be randomized. Each chunk can be identified by its location in the world, and I can use a pseudo-random number generator that will have a different seed for each chunk. Here is how I determined the seed:

[font='courier new']chunkSeed = ((chunkOffsetX << 16) + chunkOffsetY) ^ worldSeed[/font]

The chunk's 2D location creates a 32 bit int that then is XOR'ed with the seed that is used everywhere for generating the surface of the world. You might notice that if you walk 65536 blocks in one direction (maybe if you're a voxel granddad) the same seeds will be produced again. I don't think it's an issue for now, as that's a very far distance to travel and repeated object placement will likely go unnoticed if you are moving around the world for that long. The world seed will still have an influence on this item placement later on, so things may not even be 100% the same then.

Random values are used for almost everything in tree generation, from its location in the chunk, trunk height and foliage dimensions. Spheres can now be ellipsoids and I can probably add several of them in one tree to make their forms look more varied and natural.

There will be cases where parts of the tree will intersect other chunks, so other chunks need that tree information. What did I do here? On every chunk, I actually compute the random values for all 8 chunks surrounding it, and then piece together that information by attempting to render parts of the trees on each chunk.

That sounds terribly inefficient on paper, and it probably is, but the chunks are still made as fast as ever. The tree generation code is still fairly simplistic compared to computing 3D simplex noise, plus I do not have to loop through every single voxel to see if something needs to go there (I'd have to check for out of bounds voxels anyways, otherwise the program will crash for trying to access an array element that isn't there).

So here are the results of how that looks:


(Not Bad image macro goes here)
Keep in mind this is with just one tree randomly placed in each chunk, where elevation is below 80. I first thought I needed 3 or 4 trees per chunk to look decent, but I plan on making the trees bigger anyways. A dense jungle might get away with 2 per chunk, though.

Next, I'll refine the tree generation to make more interesting shapes for the trunk and leaves, and then work on varying the colors with the trees and terrain!
Sign in to follow this  


Recommended Comments

Those mountains look glorious! Mind if I ask how you layer the noise to make them look like that? Most of mine end up much rougher regardless of the number of layers....

Share this comment

Link to comment

Those mountains look glorious! Mind if I ask how you layer the noise to make them look like that? Most of mine end up much rougher regardless of the number of layers....


It's a combination of two different passes with the Simplex noise octaves and then masking one of them with height thresholds. The first pass has one or two (I think) octaves of Simplex noise using  low frequencies (1 / n with n being in the low hundreds). This gives you only the smooth valleys and plains.


Then I do a second pass using higher frequencies, with the lowest still higher than the highest in the first pass. The noise function returns a range of -1 to 1 values. For the second pass I convert to absolute values, so the little valleys become more bumps. This creates round looking bumps instead of looking rough, which may not be true to reality but good enough to look at.


Finally, I use a height threshold to combine the two. Above some height X of the first pass, I add the second pass to it, and below, I just use the first pass. That's how I can keep smooth terrain on valleys while adding the bumpy peaks in higher altitudes. I tested several thresholds to get a balance of mountains and valleys that I like.

Share this comment

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!