Thursday, August 1, 2013

Gloomstone Cave: Texture Splatting and Sets, Music Fades

The best way to make an engine is to make a game with it. That's why pretty much all of my updates include some sort of practical 'demo room' scenario. Building out engine infrastructure in a vacuum is going to leave you with a worthless engine, so each update includes some sort of practical and realistic gameplay situation to help me discover gaps in the engine features.

Ever since adding layer-over-layer functionality and minor changes to the behavior structure, I knew I was just about ready to start building real levels. A delay in asset creation due to Comic-Con meant I had about a week to do something else, so that's where the distortion effects update came into play.

So, armed with some fresh cave tiles, I started making a game by designing one of the first accessible areas of the game, Gloomstone Cave. Two missing engine features quickly became apparent after I made a few interconnected rooms:

1. Randomized texture sets

Check out this level editor screenshot from a (fairly empty) cave room:

Design time...

Now check out that very same spot, in-game:

...and run time.

Notice anything? It's subtle, but there are actually two separate floor tiles--one is 'plain' and one has a slight pebble decoration to it. But if you look at the level editor, you'll see that it's all just one tile.

I'm not claiming this is some kind of technical wonder. It's not--it actually only took me a few minutes to add random texture set metadata to the texture editor, seen below.

A screenshot of the texture editor for a single texture, cave_floor

So, if two textures are tagged with the same 'random set' property, it means at run-time, when the level loads, a random texture from that set will be selected. The reason for this? There's absolutely no point in wasting design time picking out from a set of tiles when the goal is to just randomize them anyway. The minute I caught myself alternating between the pebbled and regular floor tile, I realized that adding this little feature would save me hours of time later.

2. Texture Splatting

Another thing I noticed when designing the cave floor is that it was boring with the same tile (well, two similar tiles) everywhere. I had a temporary 'path' tile to use, which looks like this:

A temporary path tile, straight from Google Image Search

Problem is, this looks pretty mixed in with the cave floor:


The naive solution to this issue is to make nice 'edge' versions of the tile so that it blends in. I might need one for each side--I can't just rotate them, since that would throw off the tiling of the rest of the image. Oh, and wait, I need 4 more for the corners. Oh, that's just the convex corners, I'll need 4 more for concave corners. Now we're talking about 12 tiles.

That's doable, but a pain in the ass to maintain. If I want another path--or grass growing on the cave floor, or water--do I have to create 12 more tiles for each one? When I make a change to one of those tiles, do I have to update all 12? Yes. That sucks.

What if I could just dynamically apply an alpha map to the single tile, and do it at run-time instead of design time? That's sort of the idea behind Texture Splatting. So, I added that to the engine. Here's how it works.

1. Create a custom splat map

I still have to create those 12 'edge tiles', but I create it as a re-usable alpha map. Here's what it looks like currently. I will probably add a lot more of these, including some more rugged ones. I call it my 'splat map.'

That's actually 12 square textures, even though it kind of looks like 6.

2. Pass in the splat map texture along with texture coordinates to the fragment shader.

A few of my shaders now have a segment of code like this:

   if (fragSplatUV.x >= 0)
     result.a *= texture(splatTexture, fragSplatUV).r;

So, entities (which includes tiles) have optional 'splat coordinates' that get passed in. I use -1 for the x value to indicate 'no splat', which saves me from having to do an extra texture lookup (which is probably true for about 95% of the entities). Note that I only use the red component of the splat map; maybe in the future I could use the same texture for other metadata, and only store splats in the red channel.

3. Apply splats in the level editor

Pressing 'b' in the level editor launches the splat picker:

The splat selector

4. Make things a bit prettier

Here's a result of me adding a bunch of splats to that ugly segment:

Looks better than before

And here it is with an old grass texture:

It's grassy now

So, even with minimal extra textures, it looks much better! Of course, it still isn't perfect--it still looks slightly artificial instead of organic. But that's just a matter of updating the splat maps to have more rugged and randomized edges instead of the straight lines and perfect curves that are there now.

That's all for the texture updates.

3. Music Fading

Just a quick little feature, I made it music transitions smoothly from one area to another. Here is a little video that shows that, as well as demonstrating a basic walk-around through various empty sections (I'll be making them more interesting really soon). Also, check out the cool light shaft effect at the cave entrance!

Note that I'm using palace textures outside since I don't have the proper outdoor cave textures yet.

Enjoy the video and see you time!

No comments:

Post a Comment