Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (491)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  2D Simplex noise infinite terrain generation  (Read 4894 times)
0 Members and 1 Guest are viewing this topic.
Offline marcuiulian13

Senior Member


Medals: 5
Exp: 3 years



« Posted 2013-05-29 20:31:13 »

Hello!

Long time since my last question (i hope this is good). Grin
I'm struggling these days to achive a infinite map generation in a 2D top-down game. I've tried many noise algorythms, and finally i've sticked with matheus23's implementation from his utils library (https://github.com/matheus23/Utils), more exactly, with his SimplexNoiseLazy2.

The problem i have is the terrain continuity.
As you can see in the next pictures, if i call the get method from the noise with just x and y (tile's coordinates in chunk (from 0 to 15)), i get a scattered terrain, somehow random.
If i call the get method with x / A and y / A (A is a float), i get a smooth terrain, but it is broken, but rellatively correct. What i see is that A represents the width and the height of the generated noise.




P.S.: In both images i used 8 octaves and smoothness 2.

Can anyone help me with this problem?

Getting a project done is by far the most hard thing in game development.
Online philfrei
« Reply #1 - Posted 2013-05-30 03:28:13 »

I'm not clear what the question is.

8 octaves seems like overkill, but shouldn't hurt anything as long as the component octaves are properly balanced. Are you doing a "fractal" expansion (what Ken Perlin calls "Sum 1/f Noise")?

I've been working on and off on a Perlin noise visualizer that can be run as an Applet, it you want to take a look at some of the issues around coding a terrain generator. There's a *cringe worthy* tutorial (I need to rewrite, or find someone with more writing skills to do it for the project) with a section on terrain. If you call up the visualizer, the menu bar has a "Tutorial" option under the "View" option.

http://www.java-gaming.org/topics/simplex-noise-experiments-towards-procedural-generation/27163/view.html

http://hexara.com/SimplexBuilder.html

How many layers of topography are you supporting? In my example, I was mapping to a ColorMap with 7 or 8 different colors and 256 gradations total between them. Looks like you are using much less than that. I also decided to skip octaves in my example, as it seemed like using 1, 4, 16, 64 was actually a decent map. There's code examples, but I can't seem to copy and paste from it. (Add THAT to the queue of things to fix.  Tongue )

The "final" terrain image from the SiVi tool is scrolled to the right. (Is there a way to scale an image in the supplied link, or do I have to do that at my end where it is posted?) I think there's room for improvement with the color mapping, but the general ideas are there.


"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #2 - Posted 2013-05-30 04:00:34 »

Quote
As you can see in the next pictures, if i call the get method from the noise with just x and y (tile's coordinates in chunk (from 0 to 15))...

That would be your problem.

Use the same Simplex Noise for ALL chunks, and translate the position of each tile to its actual position in the world.

ie:
int realX = tileInChunkX + chunkX*chunkSize;


Where realX is passed as the position to the noise generator, tileInChunkX is the tile position from 0 to 15, chunkX is the chunk's position in chunk units, and chunkSize is the size of each chunk (in this case 16).

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline marcuiulian13

Senior Member


Medals: 5
Exp: 3 years



« Reply #3 - Posted 2013-05-30 08:18:26 »

@philfrei: My problem is not the noise generation, but its continuity.

@HeroesGraveDev: Thanks for the reply.

I am generating ech chunk with a double for loop (for tileX in chunk and for tileY in chunk), then I create a new Tile object using as its id a value based on the value returned by the noise get method:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
//Chunk generation code
public void generate() {
    for(int tileY = 0; tileY < SIZE; tileY++) {
        for(int tileX = 0; tileX < SIZE; tileX++) {
            tiles[tileY * SIZE + tileX] = new Tile(this, map.getGenerator().get(tileX + offsetX, tileY + offsetY));
        }
    }
}

//MapGenerator get method
public int get(int x, int y) {
    float noiseValue = simplexNoise.get(x, y);

    if(noiseValue > 0) {
        if(noiseValue <= 0.2f) {
            return TileType.SAND.id;
        } else if(noiseValue <= 0.4f) {
            return TileType.GRASS.id;
        } else if(noiseValue <= 0.6) {
            return TileType.TREE.id;
        } else if(noiseValue <= 0.8) {
            return TileType.DIRT.id;
        } else {
            return TileType.STONE.id;
        }
    }
    return TileType.WATER.id;
}

Getting a project done is by far the most hard thing in game development.
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2013-05-30 08:18:43 »

 persecutioncomplex persecutioncomplex

It might be, that my implementation is broken ...  Grin

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #5 - Posted 2013-05-30 08:29:17 »

Images right next to the origin look nice:


farther away, though (very, very far away at
noise.get(x+100000000, y+1000000000)
) it looks, well... broken:


I'm going to fix this. Or at least try...

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Roquen
« Reply #6 - Posted 2013-05-30 08:34:02 »

It looks like you're sampling noise at integer locations...that will yield close to white noise (just random numbers).

@matheus23: don't bother...movies did just fine with an input domain on [0,255] for decades.
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2013-05-30 08:47:12 »

It looks like you're sampling noise at integer locations...that will yield close to white noise (just random numbers).

@matheus23: don't bother...movies did just fine with an input domain on [0,255] for decades.

I tried your hashing algorithm, but Sad The noise always gets some strange characteristics when it's at far positions.
<edit>More specifically, the algorithm from here: http://www.java-gaming.org/topics/simplex-noise-3d/23962/view.html ...
But it's hard to 'port it to two dimensions' and 'port it from int's to long's' :/ </edit>

Anyways, @marc, if you try to use x and y offset as seeds, better try giving my implementation a seed. That works better Smiley
If you still have problems, tell me at what x and y positions you query the SimplexNoise Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Roquen
« Reply #8 - Posted 2013-05-30 09:34:46 »

There are two hashing functions, the simple one is awful but works good enough for me.  If you're having problems with the other...then do you have some coordinates and scale values for me?  Distance shouldn't matter for that hash.
Offline marcuiulian13

Senior Member


Medals: 5
Exp: 3 years



« Reply #9 - Posted 2013-05-30 18:41:29 »

@matheus23 You say that i shoult try making a new seed for each Tile and set its seed to offsetX * x + offsetY or something like this? I don't really understand what you said in your last post. Sorry.. Cheesy

Getting a project done is by far the most hard thing in game development.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online philfrei
« Reply #10 - Posted 2013-05-30 19:07:07 »

As Roquen said, if you use integers as your x & y inputs, you will be getting who-knows-what because the numbers will be wider than the gradient points.

Continuity will come with two things:

1) make the x & y of your tile equal to a fraction, e.g. "scale" it. I'm not sure what the best scaling fraction is for Mattheus's implementation, but for SiVi, 1/128 or 1/256 work pretty well.

2) treat the (x, y) within tiles as if they are continuations of the first tile, e.g., for a second tile to the left of the first tile, treat x within that tile as x + width-of-first-tile, and continue doing so for each tile.

For example, a tile 4 to the left of the origin would be noise((x + 3 * tileWidth)/128, y/128)

If the inputs to the noise function are doubles, you should be able to "translate" (the part that is added to the x or y) pretty darn far without running into problems.

"Greetings my friends! We are all interested in the future, for that is where you and I are going to spend the rest of our lives!" -- The Amazing Criswell
Offline marcuiulian13

Senior Member


Medals: 5
Exp: 3 years



« Reply #11 - Posted 2013-05-30 19:11:13 »

Wow  Shocked, I just found the problem. I was using as intrepolation equation 3 * t^2 + 2 * t^3 instead of  6 * t3 * t * t - 15 * t3 * t + 10 * t3. I can't belive it makes such a difference. Although, thanks everyone for help. Now I can continue developing ^^.

P.S. : @matheus23, you have one small issue with your noise: when you use negative numbers, it messes up.
The way I fixed it was to change this code from SimplexNoiseLayerLazy get method:
1  
2  
3  
4  
final int cellX0 = ((int) x / density);
final int cellY0 = ((int) y / density);
final int cellX1 = ((int) x / density) + 1;
final int cellY1 = ((int) y / density) + 1;

with
1  
2  
3  
4  
final int cellX0 = GameMath.floor(x / density);
final int cellY0 = GameMath.floor(y / density);
final int cellX1 = GameMath.floor(x / density) + 1;
final int cellY1 = GameMath.floor(y / density) + 1;

Getting a project done is by far the most hard thing in game development.
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #12 - Posted 2013-05-31 08:27:26 »

Wow  Shocked, I just found the problem. I was using as intrepolation equation 3 * t^2 + 2 * t^3 instead of  6 * t3 * t * t - 15 * t3 * t + 10 * t3. I can't belive it makes such a difference. Although, thanks everyone for help. Now I can continue developing ^^.

 Angry

Yes... it makes a difference if you use
3 * t² + 2 * t³
instead of
3 * t² - 2 * t ³

:/

<edit>And thanks for finding the mistake Smiley </edit>
<edit2>Fixed and pushed to repo</edit2>

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (29 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (38 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (35 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (48 views)
2014-08-09 21:09:32
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!