These last two weeks have been pretty busy, both in work/life and Mirage. On the mirage side, I ported the last modifier: fluvial erosion. I spent the first week writing the initial implementation and this week making it actually work.
Many moons ago I wrote a pure Python implementation of the virtual pipes hydraulic erosion algorithm. It was crazy slow. Even 10 iterations took many minutes to complete. So I ended up adapting Michel Anders’ (varkenvarken) implementation which uses numpy. Huge kudos to michael. This algorithm is already quite complex, but implementing it in numpy is some wizard-level coding 🙂
While this erosion code was quite good and I managed to refactor and tweak it for Mirage I still wanted to rewrite it in Rust. The Rust code is less restrictive, and easier to mantain and change. With parallelization and the use of GPUs in the future it will eventually perform better than the old one.
Michael based his code on this paper (with changes). I also added some changes of my own on top of that. This time around I’ve implemented the algorithm in (almost) the same way as the paper to keep it simple. And in the vein of keeping it simple, I’ve decided to call this modifier Water Erosion.
Check out the result of my first eroded terrain:
Turns out I was messing up the axis in a few places in the erosion step. Luckily it was a simple fix. Another problem was getting the variables right. These algorithms are delicate when it comes to numbers. Go too high on something and you can get all kinds of problems. Here’s what happens if you add too much water without moving the sediment properly.
After some more hours of debugging and playing with variables I finally got the good stuff:
This takes about 50 iterations to be visible and about 100 to look good. It runs fairly well for non-optimized code. I’m not planning on doing any optimizations for this version, but I will make it run in parallel for the next one. I also want to play some more with the variables to see if I can get something that looks close to this with less iterations. It will likely look rougher though, since water needs time (iterations) to move around the terrain.
Next week I’m going to keep hacking on the water erosion modifier. I still need to complete the UI and plug it into the engine. The one thing that bothers me is the settings. There are 6 settings but they only make sense if you know the equations and how it’s implemented. I want to merge these into something more intuitive.
Further on I want to add other source(s) of water. Right now the only source is rain falling ranomly on the terrain every iteration. I want to add a way to add springs which would then flow downwards and create rivers. In the future we will also have full intractive control over this erosion with something like a “rain brush” and a gizmo to position springs.
If you want to have a seat in the first row when the next version of Mirage is released you can check it out on the BlenderMarket.