3
\$\begingroup\$

I would like to generate random cave type backgrounds similar to the one shown below.

enter image description here

I doubt anything I generate will look as good as the image, but something with that feel of sharp, jagged peak should be possible.

I don't have any experience in procedural generation and as such have no idea where to start....

Note: I am using libGdx on Android

\$\endgroup\$
  • \$\begingroup\$ Minecraft uses 3D perlin noise to generate caves and stuff. Did you look into that? Maybe you can apply something similar to that to 2D to get the effect you want. \$\endgroup\$ – ashes999 Mar 22 '16 at 3:43
2
\$\begingroup\$

One easy way to do it would be to use the midpoint displacement algorithm:

  1. Start with a line representing the ceiling.
  2. At the midpoint, displace it some random amount leaving the end points where they are.
  3. Now take the resulting 2 line segments and do it to each of those (divide them in half and displace their centers by a random amount).
  4. Continue doing this until you have a shape you like. Do the same for the floor.
  5. Repeat the process for the floor, but displace upwards instead of downwards.

Also, see this answer.

\$\endgroup\$
  • \$\begingroup\$ Midpoint displacement doesn't generally give sharp peaks like OP asked about. It creates more gradual slopes. \$\endgroup\$ – ashes999 Mar 22 '16 at 3:30
  • \$\begingroup\$ True. You could do something like treat the min as 0, the max as 1 and square the values to make it more jagged. You could also add random noise to the results to make it vary more. \$\endgroup\$ – user1118321 Mar 22 '16 at 3:41
2
\$\begingroup\$

Midpoint displacement will work provided that you feed in the right sort of values.

To get sharper peaks & valleys, you need to favor high & low numbers while suppressing mid-range numbers. For instance, assume some function rnd() returns a uniform random number in the range [0-1]. Then (sin(rnd()*PI)+1)/2.0 would skew that result to favor values closer to 0 or 1. Other mathematical transformations that would work, this one happens to be easy to prototype in a spreadsheet. If you need to do this in real-time, you might want something faster than sin().

Also, I would only apply the above to the first set of values used by the midpoint displacement. On the "interior" of the algorithm, I'd use uniform noise. That being said, it's easy enough to try it both ways & see which suits you better.

One thing this solution won't do is pair up stalactites with stalagmites other than random chance. If that's a requirement, you should update the question accordingly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.