Showing posts with label water. Show all posts
Showing posts with label water. Show all posts

Tuesday, August 26, 2014

Water is Fancier Than You Think


Progress? On my project? It's more likely than you think. As you can probably see from the above picture, I've been working on water. While it may not look that impressive, this actually involved several significant changes. To get to this pretty scene, I had to do the following:
  1. Deal with having two blocks in the same spot (for water intersecting the shore).
  2. Add support for transparency.
  3. Remove internal faces from between world chunks.
  4. Add support for non-solid blocks (so that the player could walk through the water).
  5. Add support for animated textures.
Lets cover each of these in detail:

1. Deal with having two blocks in the same spot (for water intersecting the shore).

Allowing each cell to hold two different blocks would double the memory I'm using, so that wasn't a feasible solution. And if I ever needed three in the same spot, I'd be back where I started. 

The obvious answer was to use extensions (the same technique I'm using for vegetation and decals). However, I wanted the water to look like one large body, rather than a bunch of cubes. This meant eliminating internal faces. Unfortunately, extensions don't take adjacent cells into consideration during the mesh building phase.

So I introduced a new extension type for blocks. The meshing algorithm was modified to handle these the same way it handles normal blocks.

2. Add support for transparency.

For those unfamiliar with game programming, properly handling transparency is actually quite difficult. To get it looking right, you have to render the faces from back to front. Unfortunately, the most optimal way to render non-transparent things is front to back (and with blending turned off). Thus, the best solution was to create two meshes, one opaque, and one transparent. The opaque meshes are rendered first, front to back. Then blending is turned on, and the transparent faces are rendered back to front.

I also had to modify the meshing algorithm to account for the fact that transparent faces don't hide opaque ones. There are also still some problems that can arise from having multiple layers of water in the same chunk that I have yet to fix.

3. Remove internal faces from between world chunks.
Until I made this change, the meshing algorithm only took into account blocks in the same chunk. Unfortunately, this lead to underwater walls being generated between chunks. I had to modify the algorithm to take neighboring chunks into account. This also meant waiting until all those neighbors were loaded before running the meshing algorithm in the first place.

4. Add support for non-solid blocks (so that the player could walk through the water).

This was relatively easy. I simply added a flag to each material indicating whether it was solid or not (likewise with transparency). This flag could then simply be checked in physics, and non-solid blocks could be ignored.

5. Add support for animated textures.

I spent a long time thinking about ways to accomplish this. The solution I settled on ended up being stupidly simple. I simply built a table of animation info. that corresponded to each texture. This info is passed to the shader, which does some simple math to figure out which texture to draw each frame.

This did force me to start using array textures, but that also got rid of some aliasing, so it was a good move all around.



I also did a few other miscellaneous things, including some minor optimizations and bug fixes. All in all, it was a very productive week!


Tuesday, March 18, 2014

It's a Small World After All

I'm still working on large-scale terrain. I decided to try a hexagonal grid rather than a square one because it seemed more natural. Plus, it avoided the awkward question of whether or not I should have water flow diagonally. Here's a screenshot. The terrain itself looks more natural, but lakes and rivers no longer form quite as easily, which I have to work on.


Here's a screenshot showing the hexagonal cells. Each vertex is one cell. The lines show the connections between them.

One thing that's changed is that the different layers can now mix together to a degree. I'm not sure if this was a good move. It's more realistic in some ways, but the results aren't quite as interesting. Feels like two steps forward and one step back. There are still a lot of things I want to add (temperature, humidity, snow and ice, plants, etc), but I'm trying to get the parts I have now working as well as possible before adding more complexity.

Interesting fact: the area I'm simulating is roughly four square kilometers, but this can be scaled up.