Today I took a deep dive into building a loop-compatible erosion process using Filter Forge’s native components — no bitmap dependencies, no external scripting, just pure node logic. The goal was to understand how erosion works as an iterative process and to replicate the core mechanics using modular, compiled components.
Starting Point: Terrain Seed
I began with a Perlin noise heightmap, softened with a fractional blur to reduce stepping artifacts in the derivative stage. This gave me a smooth elevation field to work from — the Z-axis defining governing all downstream flow logic.
Step 1: Gradient and Angle
Using the Derivative component, I extracted ∂H/∂x and ∂H/∂y. These fed into an Arctan2(x, y) node (set to rotations), with a +0.5 offset to normalize the angle map. This gave me a directional field — essentially a terrain-aware compass.
Step 2: Slope Extraction
To derive slope, I took the Derivative of the angle map, passed it through Arctan(rotations), and normalized it by dividing with Arctan(1 × 10²⁵). This gave me a usable slope map that responds to directional curvature.
Step 3: Flow Directions
I converted the angle map to radians, then used Cosine and Sine to reconstruct a unit vector. This vector was scaled by the slope map to produce a directional flow field — a vector map encoding both direction and strength.
Step 4: Displacement Pass
Using the flow vector, I applied a single Offset to the original heightmap. This simulates directional smudge — a proto-erosion pass. I also experimented with blend modulation:
-
(1 - H) for elevation bias
-
Slope for urgency
-
Lerp((1 - H), Slope, 0.5) for stylized flow
Iteration Insight
Doing this in Filter Forge was enough for me to understand the erosion process and see why it works best as an iterative process. To really get it right, all of these steps need to be recalculated per iteration, based on the results of the prior iteration. Each pass alters the terrain, which in turn alters slope and flow direction. To simulate true erosion, all maps — gradient, angle, slope, flow — must be recalculated per iteration. Static flow logic only scratches the surface.
Closing Thoughts
This experiment helped me understand erosion not just as a visual effect, but as a recursive process. While a true procedural erosion would overwhelm it quickly, Filter Forge’s native components are surprisingly capable when used modularly, and I’m going to explore what happens with 5 to 10 step loops. To go further, I’ll come back to World Machine to see what I can do using the Code Device.






