0
\$\begingroup\$

I've been using 2d perlin noise to generate height maps for a little isometric terrain experiment. The noise value is directly related to the z-layer a tile will appear in: Math.floor(noise * 10). Perlin is great but height is now always linear and I'm not sure how to change this.

One thing I tried was making the height value go up exponentially, producing a map akin to the image attached. Now my maintains are larger and more interesting looking, but this obviously produces gaps. I'm not sure how to "pad" or 3D-ify those layers. Any pointers?

    var diff = .04;
    var zz = Math.random() * 100;
    var x, y, xx, yy;

    for (var y = 0; y < maxY; y++) {
        this.grid[y] = new Array(maxX);
        for (var x = 0; x < maxX; x++) {
            xx = 0 + x * diff;
            yy = 0 + y * diff;

            this.grid[y][x] = Math.floor(Math.pow(simplex.noise(xx, yy, zz) * 4), 2.3));
        }
    }
    return this.grid;

perlin isometric

edit: i'm sorry i'm not more clear. i'm not entirely sure what i'm asking because i'm not entirely understanding the maths. the terrain i've been trying to make starts at the base level with water. then some layers of grassy types, going into mountains. i'm not building minecraft here, i don't intend to dig around in it, but i would like to be able to rotate it sometime (replacing the tiles with cubes). right now, simplified, i'm expressing x and y as a 2d grid, with the value representing z, like so. z is really just my tile height.

var grid = [
    [1,1,1],
    [1,3,1],
    [1,1,1]
]

in this example i will draw 9 tiles, with the middle one at a height of 3 creating the gaps you see in the image. i was thinking the image would be more complete if this was a 3d grid.

var grid = [
    [
        [1,1,1],
        [1,1,1],
        [1,1,1],
    ],
    [
        [ , , ],
        [ ,2, ],
        [ , , ],
    ],
    [
        [ , , ],
        [ ,3, ],
        [ , , ],
    ]
]

blanks in this case will not be drawn. the values in the array could represent the type of tile for instance. i tried this with 3D noise but i'm very unsure how to interpret the density values (from -1 to 1). Drawing all density values under 0 (as the same tile) got me the image below which is cool, but not what i was hoping for. So far everything i've read about this does not explain what the values actually mean. translating the density values into into 'types' of terrain generates mostly nonsense, with random bits of water all over the place. the whole thing just looks like a giant cube with holes in it.

maybe i'm not making sense because what i want does not make sense, this is entirely possible. the internets is letting me down and i'm hoping some smart people can point me in the right direction.

3d noise

\$\endgroup\$
  • 3
    \$\begingroup\$ Well, since your heights are integer values, the gaps occur when the height changes by 2 or more units between two adjacent blocks. You'll have to detect that and insert extra blocks or generate wall geometry to connect them. (BTW, a quibble: since you're calculating pow(noise, 2.3), it's not "exponential", it's a power law. Exponential would be something like pow(2.3, noise), which is quite different.) \$\endgroup\$ – Nathan Reed Feb 10 '14 at 5:56
  • \$\begingroup\$ Is there supposed to be an image attached? Don't see it. \$\endgroup\$ – Trevor Powell Feb 10 '14 at 5:57
  • \$\begingroup\$ @TrevorPowell yes there is an image. it's uploaded using the stackexchange image button. i'll verify... \$\endgroup\$ – Jorg Feb 10 '14 at 6:45
  • \$\begingroup\$ @NathanReed thanks for the quibble. I'd rather use the right terminology ;) I'm aware why there are gaps. I'm now trying to figure out how to turn this into a density map (using a 3d grid). I can't seem to interpolate my z-layer to the existing x/y layer. \$\endgroup\$ – Jorg Feb 10 '14 at 6:48
  • \$\begingroup\$ The sides of your blocks aren't tall enough to draw the difference between adjacent heights; if you drew taller sprites, I think it would cover the gaps. \$\endgroup\$ – amitp Feb 10 '14 at 16:36
0
\$\begingroup\$

Your tile positions are calculated according to your isometric transformation function.

If you want to "3d-ify" this, you will need to do the following:

Determine the screen positions of the four corner points of each tile. Since every corner point is bounded by four tiles, you need to take the heights of those four tiles, and average them to get the height / screen position of the corner point that they share. You can do this either before or after your isometric transformation; it makes little difference.

Now, per tile, get these four newly calculated corner points, and perform a fill between them (polygonal fill, most easily achieved as a scanline fill). You may get pixel gaps here and there. To avoid these use point-on-side-of-line detection while scanline-filling across the entire viewport. This way you will never miss a pixel.

Now all you need to do is make sure that you do this from back to front (painter's algorithm) and you should get what you want. This will, by the way, draw backfaces. Since your display is only 2D anyway, I wouldn't worry about that bit of overdraw. It likely won't be a showstopper.

P.S. In order for characters to move smoothly between tile centres, you would linearly interpolate (lerp) them from one tile-centre height to another.

\$\endgroup\$
  • \$\begingroup\$ pixels and character movement are not really an issue - these are still tiles and their positions are fixed on a 3d grid. i'm more after a method to fill up the area underneath the height map in a semi realistic fashion because i think it would be fun to start drawing cubes instead. i did find 3d noise that generated mad caves. my math is rusty and i'm struggeling to turn density into terrain. \$\endgroup\$ – Jorg Feb 11 '14 at 11:24
  • \$\begingroup\$ @Jorg You need to draw a picture of what you are expecting to see, because right now neither Nathan, Trevor, Amit nor I have a clue. Amit is BTW a de facto legend with procedural stuff, so if he can't help you, no-one can. P.S. What relevance can "turning density into terrain" have? P.P.S. Also, I'd like you to look back at your original question and explain to us whether what you are asking now has anything at all to do with your originally-stated question. Because I see no commonality. \$\endgroup\$ – Engineer Feb 11 '14 at 11:41
  • \$\begingroup\$ i've made an edit. comments i made were made after trying to read up on the subject. i've been on amit's page before. his work on pathfinding was very illuminating. hadn't found the terrain bits yet, thanks for the link. \$\endgroup\$ – Jorg Feb 11 '14 at 12:04
  • \$\begingroup\$ i ended up backfilling tiles by scanning the height of the tiles below it: dl.dropboxusercontent.com/u/5244505/perlin/index.html \$\endgroup\$ – Jorg Feb 12 '14 at 2:04
  • \$\begingroup\$ @Jorg looks great, glad you found your solution. \$\endgroup\$ – Engineer Feb 12 '14 at 2:36

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.