Experimentation with drainage on proceduraly generated terrain

Is this a thing? Touch input would be running closer to the hardware right, but does polling by the app queue inputs or ? My project is in limbo but I don’t recall the specifics of this problem and your scene is too heavy foe my phone ;p I’ll try tablet

I think you are correct; if there are multiple touch events per frame, they get combined.

It turns out i was just forgetting how to use the touch interface. The distinction between double-touch-drag (change viewing angle) and pinch (change elevation) are easy to overlap if you aren’t careful.

If i ever do anything with this that needs accurate camera control i’ll need to fix it but for the time being it’s adequate.

Better rivers:


So i’m cheating. They don’t exactly follow the lowest points on the terrain any more; I cut the corners which makes them look more rounded.
They look much better (less like PCB traces) so i think it’s worth the compromise of not actually following the proper drainage courses.

I’m calculating where to display the rivers in a shader program.
I’ll need to duplicate that code on the CPU so we know exactly where the river is there as well so i can encourage trees to grow along the river banks (but not /in/ the river like sometimes happens at the moment).

I still need to play with colour schemes for the rivers too.

As with everything there’s some sliders in the UI so you can tune how likely rivers are to form and how thick to draw the lines.

I also had a play with skyboxes but the horizon looked silly.
I think i’ll make a change to my water material so i can have the colour cahnge towards the horizon to match whatever sky i put there…
Or maybe do it with fog.

2 Likes

So i’ve made many, many small tweaks over the last few weeks.
Some highlights:

  • I’ve stopped trees form appearing in the middle of rivers.
  • I did some work on the noise generation that seeds the landscape, tree locations, etc. You probably won’t notice from a single map but in general i think the terrain looks better.
  • I also created a task scheduler so computationally expensive functions don’t hog all the CPU. It doesn’t really make much difference once the terrain is loaded but it is less chunky while loading or adjusting the various sliders.

Known issues:

  • Occasionally a beach is very close to horizontal and you see z-fighting with the surface of the sea.
    I’m not sure what to do about this. Tweaking the camera clipping distance will help but i think it will always happen occasionally.
    I /could/ cheat and hack the terrain generation so there is always extra slope on terrain at the water’s edge. I don’t really like that option…
  • Waves still appear along lee shores. I want to make wave height a function of how far down wind of a shoreline the area of sea is. Also have them break on shores. White water, etc.
  • If you really follow the rivers, occasionally you will catch one taking a noticeable shortcut over a bit of higher ground. It flows up, over a bit of higher ground. This is due to the cheat i do to make the rivers look more curved.
    I /could/ add more code to flatten the ground whenever a river takes one of these shortcuts but i’m not going to bother just now. I might change my mind if i ever actually use these maps for anything.

Other things that are eating my time:

  • I got a new spindle for the CNC machine i’ve been building. I can now mill steel. It is very satisfying to be able to cut steel to any shape i can program.
  • I want to get back to Improve experience of camera control - #19 by Deltakosh . I have some partially complete code based on the camera controls i use in this project so i really should clean them up and submit them to the main project.

I think your project suits very well for meliorative system apps.
But in this case rivers should flow always down, as real ones :slight_smile:
It would be really interesting to take some real geo map and play with it.

I don’t actually know what a meliorative system app is.
Google doesn’t help much here.

As for not cheating with the rivers, it’s a compromise. If they follow the mesh vertexes, they look very angular.
If i was to increase the number of vertexes, i wouldn’t be able to display as big a mesh.
I’m aiming for the easy 80% here: 80% of the effect with 20% of the effort.

Meliorative system is the same as water management system.

1 Like

Ah, got you.
i’d wondered if it was something like that.

Using real wold terrain data would defeat the purpose of this project though: It’s meant to demonstrate the algorithm i developed for procedurally generating terrain that always flows downhill in O(n log(n)) time complexity.

But i agree, a lot of what i discuss in this forum topic would be applicable to any project displaying a large map.

I bet if you had tide cycles the shore would sort itself.

Hey! I really like this thread! I have been working on drainage a bit myself, however in a different environment (Rhino + Grasshopper - CAD software…). I generated streets within a research project according to the drainage direction, since our water engineer told us streets should not be pointed perpendicular to the drainage direction. The algorithm was ported to python from a javascript project.
The website is still WIP, but wont change too much.

Here is another script to analyse, how affected those streets are by drainage:

Water network analysis:

Simple drainage:

Here is the procedural streets algorithm in javascript, that I adapted:

The water network analysis is also available as javascript. So the tools are there to make a whole web app.

Maybe some resources are of interest for you, feel free to ask :slight_smile:

1 Like

This is really very interesting!
Are you going to implement real geo data for calculations?

Hi,
in my case I was involved in a research project to create assistive planning tools in rural urban Ethiopia. It stayed research until now, but we used SRTM terrain data. It is not too precise though for accurate drainage calculation.

Even with some lack of precision at least it helps to quickly visualize problem areas.
Some time ago I was involved into the Russian translation of the book “Water Resource Systems Planning and Management” and it seems to me that almost all math calculations which are described there could be nicely visuaized with the help of BabylonJS and used in real applications.

I will have a look at it. But yes, I really can imagine it! Its such a useful topic!

For pressurised water network analysis I used epanet. Seems there is now even a newer js version: https://epanetjs.com/
And I would have to look into pipe dimensioning and layout of water network, but there are also some nice papers available for generative design.

Hi,
thanks for the interest.
Your work looks interesting too. I see the parallels.

I have done as much work as i plan to on the drainage aspect of this; I am aiming for “quick and easy” terrain generation here, not an accurate erosion driven model.
I think what i have looks fairly believable (with the exceptions of a few caveats mentioned in earlier posts) so it meets my goal.

I’m probably not going to add settlements to /this/ project.
This project is intended to demonstrate my terrain generation algorithm and i feel it already achieves that.
Adding settlements would distract from the goal.

I am considering using this terrain generation and a lot of the BabylonJS code i’ve written for a game at some point in the future though.
I’ll do that as part of a separate project though.
That will need settlements.
Like your approach, GitHub - phiresky/procedural-cities: Information about procedural city generation was going to be my starting point.

Before settlements though i intend to analyse arias of interest to people to generate likely settlement spawn points.
Fertile land, river crossing points, deep water harbours would all make terrain more attractive to settlers.
Once i’ve got code to decide roughly where settlements should form, i was going to run a weighted A* algorithm to find the best route between settlements.
At this point i have enough data to feed the phiresky algorithm and i can start generating villages/towns/cities.

2 Likes

Citiez - Experiments ← found the github pages deploy of it. With a half assed explanation of what’s going on.

If you hit next step you will see the roads generate, this is throttled and can go way way faster.

and this is technically psudeo random sense its being seeded by the maps you feed it.

did this a while ago, not sure if it will help you at all. Just copy the repo and launch index.html it should be in a stable state (I hope).

Basically adds some logic to a L-like System and analyses the terrain map and the population density to start making roads. Does not make fully realistic ones yet as its scripted to just kind of find the path of least resistance but you could prolly adapt the logic fairly easy.

Most of the logic is done by the axiom class in the web-worker script if I remember right.

Got a few more things like this in the vaults if this ends up helping.

3 Likes

I’ve addressed most of my outstanding issues.

The Z fighting issue where sea surface and land get very close in height and the land is close to horizontal
i fixed by just increasing the constant value that is added each round when generating the terrain.
I do resent the fact i can’t have large salt flats a little but i don’t think anyone other than me will notice.
Also it’s not like i’m going for realism here.

Waves appearing along lee shores i’ve fixed by calculating a value for each tile how many up-wind tiles are open water. This data is passed to the shader drawing the sea surface.
This is quite low resolution so eg: small islands sometimes still have waves appearing from their lee shore.
I could easily increase resolution here but i think it’s good enough; The waves are a subtle effect. Any more work here wouldn’t really add much to how believable the scene is.
The wind in the screenshot is coming from right to left:

I did try adding breaking waves to beaches but it’s actually quite hard; There are 2 meshes at play: The seabed/land and the sea surface. The sea surface is just a big, flat rectangle that is hidden in places by the land.
The sea surface is the obvious place to display surf but i don’t have access in the shader of how deep the water is, so don’t know exactly where the shore is. If i pass that data in to the sea surface shader, at some point i will need to extrapolate between values to try and match the actual shoreline, without it looking blocky. It could be done but it’s a lot of work compared to the benefits.
I also tried adding breaking waves to the /land/ surface shader because there i do have exact height of the land and can easily calculate where the exact shoreline is but painting waves on the beach just looked silly.
I think if i wanted to do this, the right approach would be to create separate geometry just for drawing the surf on. I’d create it as a border of set width around the shoreline. Perfectly possible but outside the scope of this project.

I’ve been thinking a bit about my 3rd known issue: The fact rivers look far too angular if i let them follow the exact downhill paths they should run down.
I cheat here and round the corners, at the expense of them occasionally running up over a visible lump.
I think the right approach would to be to run my initial algorithm on a triangular mesh instead of a square one. I would bias the flowing-terrain algorithm to make sharp corners less likely in the actual geometry.

So i think i’m nearly done with this.
The one thing i would like to improve on is the framerate optimization. At the moment if you switch tabs while it’s optimizing, it keeps optimizing in the background but presumes the framerate is “0” so it never turns up the settings any higher…
Does anyone have an example of framrate optimization done well?

1 Like

To answer my own framerate question,
i have it working quite nicely now.
I monitor the actual framerate, take an average over multiple frames and compare against a target framerate (which can be set under the Debug tab).
If the actual and target framerates differ by more than a small value, i bump the level of detail.
I also had to add a cooldown timer to stop it from bumping the framerate again for a few seconds after the last bump.

There is actually code within Babylon for this (The Scene Optimizer | Babylon.js Documentation) but while it was useful to play with and work out what i needed, i found it made too many assumptions about the applicateion to get working smoothly here.

And now i really am done with this demo… (until the next thing that i spot that i find annoying…)

2 Likes

Congrats :smiley:

1 Like