• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Kylotan

Infinite terrain generation in chunks - need hints on handling chunk edges

34 posts in this topic

I do not know what function to use for the successive rounds. The value needs to be interpolated between 2 separate hashed values. I don't know how to select both the inputs to the 2 hash functions, based on the integer value of x. I need to know how to choose those 2 inputs in such a way that I get to vary a frequency parameter (by that name or another name) to alter the level of coherence between adjacent integer samples.

 

Perhaps it might be easier to think in terms of wavelength, rather than frequency.

 

Your highest frequency noise has a wavelength of one - and doubles (or whatever) each octave after that. Using integer maths, your hash inputs are just (x / w) and  ((x / w) + 1), and your interpolation ratio is (x % w) / w

 

You may want to provide the octave as an input to your noise function as well, in order to avoid weird effects with identical patterns being layered on top of each other at different scales.

Edited by Sandman
0

Share this post


Link to post
Share on other sites

Ok, I have the start of a working system, so thanks to all who've contributed. I've obviously been overthinking the original terms when a lot of them don't matter, and I worked out how to get integral values of x into fractional values falling between two hashed samples using division by a wavelength parameter, and it mostly works. I still need to work out how to use cubic interpolation instead of linear (which has some sharp edges, obviously), but then the basics will be done.

 

I'd like to be able to vary some parameters from one chunk to the next - eg. If I want one chunk to be almost flat, and one to be very hilly. I don't know the best way to guarantee they'd be continuous at the edge. I suppose I could interpolate between 2 different invocations of the function with the different parameters, if there's nothing better that I'm missing.

0

Share this post


Link to post
Share on other sites

I'd like to be able to vary some parameters from one chunk to the next - eg. If I want one chunk to be almost flat, and one to be very hilly. I don't know the best way to guarantee they'd be continuous at the edge. I suppose I could interpolate between 2 different invocations of the function with the different parameters, if there's nothing better that I'm missing.

Doing this on a chunk-by-chunk basis is asking for trouble - you are going to spend a lot of effort dealing with the resulting discontinuities.

 

It would be better to use another low-frequency procedural function to drive the interpolation between hills and plains.

0

Share this post


Link to post
Share on other sites

Sure, that would be easier, but that's not the specification I have to work with. :)

 

I refactored things a bit so that instead of generating one value for each point of the height map, I generate one for each type of potential terrain topography (eg. plains, hills, mountains) and then blend between them, based in the actual value at this grid square and those of neighbouring ones. Currently I'm doing this via a hack with 3D vectors and spherical interpolation, but I'm hoping I can generalise it to an array of contributions from each terrain type which I can normalise and use as weightings for each of the different sampled values.

0

Share this post


Link to post
Share on other sites

If it were me, I'd use a value noise function with a frequency of 1/chunksize as others have suggested for a base layer, then use that base layer in a selection function to choose between different types of terrain. The selection function takes two inputs and a control function, and using a threshold parameter and a falloff parameter (see the description for the [url=http://accidentalnoise.sourceforge.net/implicit.html#Select]CImplicitSelect[/url] function of accidental noise for details)  to smoothly select and blend between the two input types. So, say your chunks are 100x100. Then a 5x5 array of chunks might have a base layer like this:

 

908oHYF.png

 

Each "block" in the base layer roughly corresponds to a chunk. Then I would use a selection function to map between Plains and Hills, with threshold set at 0.333 and falloff set at, say, 0.2:

 

 

(The hills and plains are simply fBm fractal functions with specific frequencies and amplitudes, tweaked to suit)

 

Then a second select function, again using the base layer as a control, would be used to select between this Hills/Plains combo and Mountains, with the threshold at 0.66667 and the falloff again equal to 0.2. (Vary this value, of course, to vary the smoothness of the transition between terrain types):

 

J2uy15Y.png

 

rJPrcQZ.png

 

And there you have it. You can package all of this up into a meta-function such that for any point in the world you can call func(x,y) to get the height. Then it's a simple matter of mapping out sub-regions to your chunks as you go.

Edited by FLeBlanc
2

Share this post


Link to post
Share on other sites

That's quite interesting, and I can see that I might be able to simplify some aspects with a generalised selection function like that. However I don't get to have a smoothly varying base layer. The system has discrete per-chunk values for Grass, Hills, Mountains, etc.

 

I have already implemented a system that produces something much like in the screenshot, but achieved the smoothing across chunks by using bilinear interpolation when deciding what each position's topography weighting (ie. how much plains/hills/mountains) should be. This seems to be working well for me, and I'm quite relieved that it is equivalent in many ways to what you're describing as it shows I'm not doing something ridiculous.

Edited by Kylotan
Fixed formatting that the editor broke
1

Share this post


Link to post
Share on other sites

Kylotan could you elaborate a bit on your bilinear interpolation using discrete per-chunk values? I'm now working on a terrain that will be finite, but generated by noise based on properties of "chunks" that will be generated from voronoi cells (look at http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/). Basically:

 

  • I generate random set of points and run voronoi algorithm on it to create voronoi cells and delaunay triangulation, as described in Amit's post
  • Diagram allows me to run all sorts of terrain-building algorithms, with manual control over some details like where I want cliffs, generating rivers thanks to interconnection of voronoi cells and so on. I call this large scale detail map.
  • I generate a pixel map out of that diagram (again, like Amit) to have a finite (say 4096x496 bitmap) array of values which will describe various data. It can contain base height, biome type, humidity, temperature - all factors that later affect small scale details like how the terrain is generated, what plants are there. I can sample this bitmap by coords of chunk and know exactly what conditions are in this chunk.
  • Now I had a plan to generate perlin noise for small detail, so final terrain. I wanted to base this on sampled value from array, but I realized that single value from that map will create chunky terrain - every chunk will end exactly on its boundaries, and terrain wont blend between. So i need to smooth the transitions somehow - I also thought about blending nearby factors and using that interpolated value as input into noise function, but I haven't yet figured out how to do it best. Reading from FLeBlanc's post, thats what he uses falloff for in first picture probably, so the borders are not sharp but slightly blended.
Edited by noizex
0

Share this post


Link to post
Share on other sites

I'm facing a similar problem in my current project.

 

the world is 2500 miles by 2500 miles. Its divided up into 5 by 5 mile map squares. A map square can use one of five different procedural heightmap formulas, depending on the elevation in the map square (ocean, flat, hill, mountains, or impassable mountains). Needless to say, heightmaps at map square edges don't line up. I spent a bit of time working on this, and just about have it solved. what i do is blend the values of the two heightmaps together over a distance of 100 d3d units  from the edge. so at the edge, the height is 50% of one edge + 50% of the next edge. at 100 from the edge its 100% just the one heightmap. at 50 units from the edge, its 75% one + 25% the other, and so on. this yields beautiful seamless edges. until you get to the corners. I haven't implemented it yet, but it looks like the trick is to "zip up" (average together) all the seams running north south, then use those results to zip up the seams running east west. a method like this doesn't care about the procedure used to create the heightmaps, so you wouldn't have to worry about finding a noise function that works. you could use anything you wanted, then just "zip up" the seams.

0

Share this post


Link to post
Share on other sites

Kylotan could you elaborate a bit on your bilinear interpolation using discrete per-chunk values?

 

Basically for any position in the world, I collect the 4 nearest per-chunk terrain types. This is done by subtracting half a chunk from the x and y directions, then checking the chunk values at (chunkX, chunkY), (chunkX+1, chunkY), (chunkX, chunkY+1), and (chunkX+1, chunkY+1).

 

Interpolating between them is a bit tricky because the terrain types are stored in an enumeration and obviously you can't just linearly interpolate along that. So I create a vector for each chunk that holds the chunk's weight for each of the terrain types. This will be 1 for the chunk's designated type and 0 for everything else, eg. (0,1,0) if I had 3 terrain types of Plains/Hills/Mountain and this was a hill.

 

Then I can interpolate between those, which will give me a value like (0.6, 0.4, 0) for an area just inside a Plains chunk, next to a Hills chunk. So I run the noise generator on this position for the Plains and for the Hills, then use the interpolated values to weight the sum, ie. PlainsNoise * 0.6 + HillsNoise * 0.4.

 

I had a plan to generate perlin noise for small detail, so final terrain. I wanted to base this on sampled value from array, but I realized that single value from that map will create chunky terrain - every chunk will end exactly on its boundaries, and terrain wont blend between.

 

In your situation I don't think you need to try and blend anything. If you're just generating fine detail and that detail is the same everywhere then you can just add the noise to whatever is already there and the values should be continuous as long as the underlying terrain is continuous and the noise is continuous also. To achieve that, you just need to ensure that the noise sampling wraps around. Most implementations of noise already do that. You'll have the problem I did, in that most implementations assume the resolution and dimensions of the world follow the patch of noise rather than vice versa, but it's simple to fix that once you get your head around it (which only took me about 20 forum posts above. ;) )

0

Share this post


Link to post
Share on other sites

I spent a bit of time working on this, and just about have it solved. what i do is blend the values of the two heightmaps together over a distance of 100 d3d units from the edge. so at the edge, the height is 50% of one edge + 50% of the next edge. at 100 from the edge its 100% just the one heightmap. at 50 units from the edge, its 75% one + 25% the other, and so on. this yields beautiful seamless edges. until you get to the corners.

 

That's basically what I do, except I blend everywhere rather than just at edges. So in the middle of a section, that section contributes 100% of the value. As you move towards the edge of the section, that drops linearly to 50% of the value, plus 50% of the next section's value. I do this with linear interpolation for now, so I could change it to only blend nearer the edges by scaling the input values.

 

The problem with corners is solved by bilinearly interpolating across the 4 nearest sections. You can do it the way I described in my previous post, although there may be a simpler way to achieve the same effect - my attempt was shaped somewhat by the code I had already written.

Edited by Kylotan
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0