Hacker News new | past | comments | ask | show | jobs | submit login
Realistic terrain in 130 lines of JavaScript (playfuljs.com)
339 points by hunterloftis on May 12, 2014 | hide | past | favorite | 56 comments

Just a small note, not to sound snooty, just to educate people on what realistic terrain looks like...

This is what midpoint displacement looks like as a heightmap: http://imgur.com/ksETpO0,7gykFEV#0 This is what realistic terrain looks like (this is based on real-world heightmap data): http://imgur.com/ksETpO0,7gykFEV#1

That said, midpoint displacement, perlin/simplex noise, etc are good for modeling terrain at a less macroscopic scale and are plenty sufficient for the use of most games.

To add another note, as complex as real world terrain is, you can generate those fractal mountain patterns and drainage basins algorithmically with a bit of work. There are many ways to go about it, one would be recursive spacial partitioning, another would be to explicitly grow out a tree pattern while minding collision and proximity to other branches. Also, it is possible to use diffusion limited aggregation or erosion simulation but I have been down both those routes and they are not as easy to get good results with.

Further reading:

1. A semi-standard textbook on the subject, but now a bit dated (don't be fooled by the 2002 date on the 3rd ed., most of the text is from the 1st ed): http://www.amazon.com/Texturing-Modeling-Third-Edition-Proce...

2. A more recent but much shorter survey paper: http://graphics.tudelft.nl/Publications-new/2009/SDGTB09a/SD...

Thanks for this! I've been looking for resources on building out lifelike macro-terrain-structures.

Reminds me of this - pretty good looking terrain + animation + sound in a 4 kilobyte executable:


How it was done:


I like this one even more because it is procedural. No height map needed.

Thank you... What people don't realize is that "Random Noise" doesn't actually occur that often in real terrain. The bump tool in game engines is the bain of realistic terrain everywhere.

This: http://i.imgur.com/DFXMmY8.jpg doesn't generally happen in nature.

Interesting. Those branchy ridge shapes look a lot like Diffusion-Limited Aggregate patterns. But then, I guess they didn't call it "universality" for nothing :)

They also reminded me a bit of GIMP's "Solid Noise" rendering with the "Turbulence" setting switched on. I rendered one, and turns out it doesn't quite look as good (cough), but now I wonder whether this would give a bit more realistic height map: http://imgur.com/oRlZ191

On the other hand, like you say, for terrains for videogames are always best generated by taking any of these algorithms, and mercilessly tweaking the parameters, post-processing, etc until it just looks sufficiently good. Actual physical realism comes into second place (and it should, like most game physics).

I've been working on a WebGL terrain engine recently -- you can try it out and switch on the "Turbulent" flag to see the results :)


Using a noise function I produced similar turbulence once. Here was my result (it does, IMHO, look a bit better than vanilla noise):


Is this the same algorithm for the cloud filter from Adobe Photoshop?

I believe photoshop uses Perlin noise (could be wrong)

this looks more like perlin noise to me...

I agree it looks more like Perlin noise due to the finer detail not seen in diamond square [1] and the lack of directional artifacts in midpoint displacement [2].

[1] http://www.gameprogrammer.com/fractal/heightmap.jpg

[2] http://upload.wikimedia.org/wikipedia/en/9/96/Plasmafractal....

Awesome! Thanks for the link.

There was a Clojure example of this algorithm posted a few months back. Funnily enough, it's been in my "read later" bookmarks for a while now and I just got around to reading it this morning before I saw this post.


Nice demo. I made a terrain rendering engine/demo in WebGL a few months back, that used Perlin noise: http://felixpalmer.github.io/lod-terrain/

If anyone wants to play around with Hunter's algorithm in WebGL, it should be pretty straightforward to swap out the Perlin Noise implementation for his. Note the shaders do a fractal sampling of the the height map, so you may want to disable this.

Clicking "how does this work?" leads to the HTML source of the link target to be shown in plain-text instead of being rendered. Win7, both in Chrome and Firefox.....

Yes, I know - my blog is ruining my morning. Quick fix is to remove the trailing slash, i.e. go to http://www.pheelicks.com/2014/03/rendering-large-terrains instead.

If anyone using WordPress + W3TC has hit this I'd be grateful for pointers to a fix

I love how you're using a simple but effective dynamic LoD. I'm going to riff on this a bit with a first-person ground-level camera.

I made a quick first pass at an interactive WebGL version this evening. http://callum.com/sandbox/webglex/webgl_terrain/ - ground realism needs a bit of work :) but it was a lot of fun. Thanks for sharing your code Hunter.

Is there any way to control the demo? It doesnt seem to respond to mouse or keyboard input.

I made a jsfiddle and added dat.gui http://workshop.chromeexperiments.com/examples/gui/#1--Basic... so you can modify the "detail" parameter to change the terrain without requiring a page refresh http://jsfiddle.net/kachhalimbu/br8Xd/1/ Full screen result here http://jsfiddle.net/kachhalimbu/br8Xd/1/embedded/result/

It only draws a single perspective, so the only control you have is to refresh the page to get a new random bit of terrain.

What i like most about this demo is that the code is actually very readable, and the blog article explains it very well. Most of the times the code for these kinds of demos looks like line noise :)

Perlin noise is another good algorithm for terrain generation.


I like Perlin in situations where its repetitiveness won't negatively impact the simulation, or as an additional layer of pseudo-natural-randomness on top of other algorithms.

can this algorithm be run lazily? ie, can you continue to generate continuous terrain using this technique or do you need to generate the whole map ahead of time?

It can be run lazily in two ways: first, you can lazily add detail (ie, render down to a specific level of detail and postpone the rest); second, you can lazily build grid blocks out to the horizon (eg, for walking around a terrain first-person). So detail vs size laziness.

Reminds me of the results easy to achieve with Bryce3D back in the mid 90's. They had a pretty great terrain engine. I don't think they're making Bryce any more. It would be great if they could release some of that code.

I remember that one, apparently it is still being sold, but development seems to have stalled: http://www.daz3d.com/bryce-7-pro/

I guess Maya ate their lunch. Funny, from the screenshots, they've not changed the interface in a decade and a half. The much lower price is nice, though.

For those who only want to look at the result(s)


Refreshing the page will generate a new terrain

It'd be interesting to see an animation of the diamond/square iteration progressing in 3D, starting with a flat surface and ending with the finished terrain :)

This midpoint displacement algorithm is also how a lot of the "plasma" effects from 1990s-era PC demos were created.

after thinking about this one for a while, it occurred to me that this really helps illustrate the point of 'Life May Be A Computer Simulation'. Take this world creation a step further, and rather than teaching a computer how to create rocks, each one slightly different, imagine creating humans, each one slightly different. If you think about 'God' as just some alien programmer dude, it helps make so much sense of the world. How can a caring God let so many terrible things happen to us humans? Well, how much empathy do you feel about each rock in this program? When you click refresh, and create a whole new world, do you stop and think about all the exist rocks you are 'killing'? If we are living in a computer simulation, perhaps our creator doesn't even realize we are sentient?

You realize you just explained a caring God by saying he doesn't care, right?

I meant, a common human question is "if there is a caring God, how can there be so much suffering in the world?" And maybe the answer is, human pain means nothing to him the same way computer generated rock pain means nothing to us.

Brings me back to a ray casting experiment I did a while ago [1]. I always wanted to revisit it to include a terrain generation step (it uses a pregenerated height map). Now I have an excuse! ;)

[1] http://namuol.github.io/earf-html5

Wow! Really fantastic. I've already linked to your raycaster; let me know if you build one that dynamically generates the terrain as well.

I was playing with something similar a while ago. It's a procedurally generated overlay for Google Maps: http://dbbert.github.io/secondworld/

Some of you might find this algorithm I created a few years ago interesting: http://ovgl.org/view_topic.php?topic=91JL96IHFS

Reminds me of T'Rain.

I remember implementing this on a Sam Coupe from the description in (either BYTE or Dr Dobbs, I forget) back in ~1987. Somewhat slower and lower resolution, of course...

Diamond-square has a bug/limitation in that it creates seams. There are better solutions :).

stuff like this makes me remember why I love programming

I think implementing parallel computing using webworkers would be a good item for the "What's Next" list of suggestions.


You can simplify this even further by using frameworks like lodash / underscore or ES6 native methods.

This is awesome!! nice job!

I may just be a prick, but seeing this promoted as a variant of the midpoint displacement algorithm for terrain generation seem far less gimmicky. "X done in Y lines of Z" Whoop-dee freakin' do.

Still, cool algorithm.

Great tutorial on a fun topic!

Had to put "JavaScript" into the title - typical HN... It was about algorithm rather than a language.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact