Tile / Texture blending techniques.
I have a "C" program that will be used to create maps from a game using ImageMagick. Each room in the game will be assigned a texture and possibly wall textures, other artifacts in the room, a noise layer to mix things up, etc.
I wanted to ask the pros on the board, if you knew you were going to have to blend any number of square textures into any number of other textures, what approach would you use to get the best feel overall? A gradient on a layer mask? Blurring / merging the edges? Something else? Each tile is 50x50 so there isn't much space to work with.
The attached image is just for example purposes, it's not a real map -- the center part of it very well could be though. The square paving onto the grass may be ok if it isn't a ruins, but the light grass to dark grass transition isn't. I can play around with merging (for example) 2 grass textures and get it just right - but that mode won't work when I get to blending the path outside a temple with the desert surrounding it.
In many cases, I may not even know what textures are being used - dungeon creators in the game will be free to use their own textures.
So, what I'm hoping to get is opinions / advice on the best way to approach this that will work overall. I realize this might mean that none of the blending is ever the "best" for the two tiles being blending, but a good compromise that will work overall.
I've read so many different techniques that can be used --- too many options and little feel for what is likely to be the best approach. I'll be doing lots of trial and error of course, but any advice is greatly appreciated.
I'd start off with a straightforward blur on the edges to have them merge into each other softly. That's probably going to be the most robust. Following that, if you can distort the edges a little to get a more random edge that will help to break up the appearance of straightforward squares.
I'll be interested to see how this goes for you.
Fantasy Map Blog
| My food illustration
Everything I post is free for use and redistribution under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 licence, except where noted otherwise in the thread.
What I think you need to do is make an over sized texture and mask set. So say your ascii code means you generate a 100x100 square for it, then generate a 150x150 texture and make a mask which is 100x100 white in 150x150 black image. Then blur mask a lot so it fades down just before the edge of the 100x100 and fades to nothing after the 100x100 square in middle. Then place them side by side. Align all of these over sized tiles on a 100x100 grid.
Thanks Redrobes, I'll give that a try. After some experimentation I got the results below and I think this is a basic version of what you were saying done a different way.
The tiles on the left just have a slight blur at the edges based on Torstan's suggestion - although I probably overdid them.
The tiles on the right were done by taking a copy of each set of tiles to the right of it, pasting it over the set to the left, then using a layer mask with a black to white gradient to allow it to gradually fade in over the width of the tile.
Still needs some work around the edges (blurring the edges of the gradient possibly, or adding some noise), but it's starting to look promising.
If I go with this approach I'll have to include a "precedence" value on the textures so the code knows which would be overlapped onto which and 3 (or more) way overlaps could still be tricky. Would like to experiment more with only overlapping them by 50% etc.
Part of the challenge is that while I have a lot of flexibility in ImageMagick, it is just being used to prototype this - the actual game client has limited rendering capabilities. It does have the ability to lay one image over another using an alpha mask though, so using either your blur approach or continuing with this gradient idea I could include a few masks in the client for this type of thing.
One interesting approach I did see on a gaming forum was to have a base texture in an area. For example, a forest might have a forest floor texture and only ever have transitions from that to other textures.
By the way, I did a lot of googling on this and there were lots of questions with not too many answers, so I'll keep posting results as I make changes.
With that in mind, does it make sense to ask a mod to move this to WIP rather than a question in the general forum?
The classic approach to this problem is to make blending tiles. That way you can get good looking results and keep the engine very simple.
If you don't want to do this (lack of an artist and/or memory is the usual problem) then one solution is to apply an alpha mask as Redrobes suggested. If you go that route, I would recommend that you have an option to apply varying amounts of masking to each edge of the tile (that's 4 more numbers per tile), which allows the person doing the level development to allow some edges of tiles to abut without blending and other edges to blend as you see fit. Basically you have an alpha ramp for each side that you composite together. 4 or 8 ramps will allow good flexibility at relatively minimal memory footprint (4 ramps costs you an 8 bits per tile and 8 ramps costs 12 bits over the base implementation). A small number of ramps has the advantage that you can composite them together offline and store the final alpha images.
I wholeheartedly recommend supporting alpha (transparency) in your textures in addition to the blending operation. That way you can have the traditional 9 tiles for each type of terrain (one for each edge plus one repeating tile) for hard edges and still allow blending for other operations.
Are you planning for hardware acceleration or doing software rendering? There are some optimizations for software rendering that you need to do at design time that may or may not be important for hardware rendering.
As far as determining the best way to allow stacks of tiles, the simplest way is to do multiple layers. Each layer has the full rectangular block of tiles. Upper layers will be mostly empty tiles so RLE compression would be very helpful for storing the layer data in memory and on disk.
It's been a long time since I did a 2D tile engine.