3
\$\begingroup\$

I made a Java program which generates a random map based on Perlin Noise + Poisson Algorithm + Voronoi Diagram. Here you can see a generated map. White are caves, black is empty.

enter image description here

The problem is that my character will go through this caves so I need to zoom this image to see only a big piece of where I am. But when I zoom in, the image obviously gets pixelated and looks really bad. So I save it as an svg image and the quality now is perfect but as far as I have read svg images are slow to render and 2D Games Engine (like SFML, SDL) can't render them.

The approach I have read about is that maps are tiled based, a tile size depending on zoom level, but this is a randomly generated map and zooming in svg image to generate the tiles and save the tiles to formats like png, jpeg, would be very slow (Or I am wrong?).

What can I do here? I have searched how to zoom the Perlin Noise function but it isn't a fractal noise so I can't.

Thank you in advance for your help! I am new in game development!

\$\endgroup\$
4
  • 4
    \$\begingroup\$ Don't generate an image. Use the noise data to generate polygons and render it. Then you can zoom and pan at your leisure. \$\endgroup\$
    – House
    Jun 6, 2013 at 20:50
  • \$\begingroup\$ Mmm great advice, I didn't think about it. My game is in C++ but my map generator is in java so I will see top export the map polygons to an xml file or something like that. \$\endgroup\$
    – Andres
    Jun 7, 2013 at 0:16
  • \$\begingroup\$ @Andres Is there a particular reason you're using a map generator in Java and your game itself is in C++? If you wrote the map generator, it shouldn't be all that hard to port it over, unless there's a library it uses that isn't available for C++. If not, there are likely many Voronoi shape generators available for C++. Also, as an extra question: What does the grey represent, if white is empty and black is wall? \$\endgroup\$
    – anon
    Jan 15, 2015 at 1:07
  • \$\begingroup\$ @QPaysTaxes I did the map generator just for fun I'm a Java developer and don't know much about java. I wasn't developing any game at that time, just had curiosity how to show it in an efficient way in SFML. The gray color should be eliminated by using a sharper gradient, I posted the code I used here: github.com/dragondgold/Map-Generator \$\endgroup\$
    – Andres
    Jan 15, 2015 at 1:17

3 Answers 3

4
\$\begingroup\$

This sounds like a good situation to use Signed Distance Fields. It's often used for text rendering to achieve high quality and sharp results when zooming (and rotating), but it can also be used for any black & white images. See this video and the image below.

Example image from Valve

Typically when text is prerasterized to bitmaps, each pixel stores the alpha value. 0 means transparent, 1 means opaque and values between are semitransparent due to antialiasing the edges. With signed distance fields the idea is to create a bitmap where each pixel stores the distance to the nearest edge. Values < 0 are outside the shape and values > 0 are inside the shape. When rendering, this information is read from the bitmap and the alpha value is decided on runtime based on the distance and "spread". Spread here means how sharp you want the edge to be, usually chosen so that the resulting antialiased edge is no wider than 1 pixel on the screen.

The nice thing about distance fields is that when zoomed in, the distances to straight edges stay accurate when the bitmap is sampled with bilinear filtering. This allows arbitrary zooming without pixelating or blurring. You just need to provide the spread matching the zoom level. This technique is also very fast to render, as it only requires a custom shader with a single texture lookup + some simple math. This is going to be a lot faster than polygon based methods. Distance fields also allows some effects easily, mainly borders around or inside the shapes: [freetype-gl]

Example image with effects

The generation of the distance field can be a problem, as it's not trivial to calculate it from arbitrary shapes. Fortunately for you it should be pretty straigthforward, as you already seem have the distance information available as you are generating a voronoi diagram.

An additional bonus from distance fields is that it can be very friendly for some physics or lighting calculations. As an example PixelJunk Shooter used it for collisions.

The only problem I can see for your case seems to be that your map is not black and white. From the description it's not clear what the different shades of gray indicate. You could just sample the colors from traditional bitmaps or have multiple distance fields, one for each color. Or you could invent something totally different, but it all depends what you want to do.

\$\endgroup\$
1
  • \$\begingroup\$ Wow, very interesting method. But it seems a little complex to implement and I can't fully understand it so I will generate a file with the data of the map as suggested above. +1 for the great info! :) \$\endgroup\$
    – Andres
    Jun 13, 2013 at 1:19
1
\$\begingroup\$

Currently, you are generating a map in a format that is difficult to use.

Maybe you need use the algorithm for the Perlin Noise to generate a tiled map, instead of an image.

\$\endgroup\$
1
  • 8
    \$\begingroup\$ This is a comment, not an answer. \$\endgroup\$
    – House
    Jun 6, 2013 at 20:47
0
\$\begingroup\$

Divide the map in chunks of tiles, lets say chunks of 32x32 tiles, and create a mesh with the geometry of that chunk and map each 4 vertex of each tile with a tileset texture. Build all the map using those chunks join together and draw only the ones visible to improve performance. Use the texture only as reference to know the type of tile to draw at each position.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .