Overall terrain generation process
World size and scale
You should start from watching this video with details on world size and scale:
The world above sea level from the “Open World Bakery” point of view is a cube with the side of 1.0. Additionally there is a -0.01-height space beneath the ocean level space below, so effective height is 1.01 and it is stretched from -0.01 to 0.1.
When you position the hill at 0.5:0.5 it is going to be right in the middle of the map. And if this hill has a height of 1.5 it will be cut so it will have a plateau at the level of the world roof, which is 1, so about a third of the height will not be there.
Also if you create a hill that has a height less than 0.01, say of 0.005, this hill will remain below the sea level.
The important consequence of this is that the landscape does not exactly “scale” when you bake it. Beach is expected to be, for example, 4 meters/voxels wide. So it is defined in absolute units. While terrain blocks are defined in relative. This 6-voxels-wide beach could be 0.024 in the relative space, or it could be 0. 0.0015. Same is even more true for water- and erosion-related processes. Erosion is calculated in absolute space, so one voxel produces, say, 1.0 water. If above the target voxel there is a slope of length 0.02 that could mean this voxel will get a stream of power 52 or of power 410. Which will, obviously, wash more soil etc. etc.
So you can see this process in action in the video above and on the following HiRes pictures (same landscape baked in 4 different resolutions):
Terrain generation sequence
Generation of the terrain follows this order:
- Blank terrain generated at the level of see bottom (-0.01 by default). Implemented through InitHeightmap.
- Hills are placed on this flat surface. See the OpenWorldBakery concepts video for the answer to “why do you use this approach”. This stage produces base surface, enchanter UOWB_RandomHeightMapFill_Enchanter is used. Hills are ancestor classes of UOWB_Plane, see some details there.
- Each hill has its base shape, like Cone or Hemisphere
- Each hill has some individual systematic distortions attached, like ripple or convex
- Then hills (or groups of hills altogether) are subjected to non-systematic, random noise distortion.
- Each hill can have predefined amount of randomness in it's distortions and positioning
- Then on the resulting surface (after all hills are in place) erosion is applied. Depending on the setup this stage (all Enchanters except UOWB_RandomHeightMapFill_Enchanter are responsible for erosion of already pre-existing terrain. That's what you can do
- Generate soil coverage. By default all landscape is created from rock, which means it resists washing and is not a subject of landslides. So you call UOWB_RandomTerrainGenerateSoil_Enchanter to turn some surface rock to the soil.
- Smooth terrain a little bit, removing sharp angles and low-level noise, see UOWB_BlurTerrain_Enchanter
- Perform landslides/form screes. Removes soil from steep slopes, distributes soil reasonably down the slope. For a more spectacular look you may use it several times with different angles to get a smooth surface. For example instead of
- soil, power 1
- landslides, 35°
- you can run sequence
- soil power 0.4
- landslides 18°
- soil power 0.3
- landslides 28°
- soil power 0.3
- landslides, 35°
- which will produce much smoother terrain, than the default one. Implemented in UOWB_LandslideSoil_Enchanter
- Markup lakes. Asides from obvious usage to place lakes where there is a hole in the surface without a drain, this step is required before calculating streams from. Implemented in UOWB_MarkLakesCalcWaterLevel_Enchanter.
- Cleanup lakes. Generally angorythm of UOWB_MarkLakesCalcWaterLevel_Enchanter may produce “lakes” of size 1 and 0.02 meters deep. So this enchanter makes sure only those who are worthy remain, others will be turned to swamps. Depending on the setup, swamps gain soil not to match “water level”, but the water level with some random variations. This renders terrain unusable for streams calculations, because new “pools” may arise, but produces much more attracting terrain and, also, when it comes to water flow calculations - it produces nice random rivers instead of straight-line streams you get on the water surface otherwise. Implemented in UOWB_LakesToSwamps_Enchanter.
- Streams calculation. By itself does not change the terrain surface, but this stage is required for both riverbed digging and water erosion (see below). Implemented in UOWB_CalcStreamsFlow_Enchanter
- Water erosion. Based on calculated water streams removes soil from steep slopes, deposits soil on lakes and flat places. Digs wide valleys, but does not perform landslides afterwards. May affect rocks and soil, by default rocks are 10 times harder to wash, than soil. Implemented in UOWB_WaterErrosion_Enchanter
- Dig riverbeds - based on Streams calculation, creates riverbeds where the streams are. Correctly marks lakes exits, etc, prepares terrain to naturally-looking water overlapping calc (see below). Implemented in UOWB_RiverBedDigger_Enchanter
- Water overlap calc and river surface deployment. Depending on the amount of water and slope places flowing streams surfaces where they should be. Calculates final streams direction. Without riverbeds digging may produce strange results, bit for modeling lava that could be desirable, generally you would use the sequence like this:
- Markup lakes
- Cleanup lakes with DrySwampNoise = 0.0
- Streams calculation
- Dig riverbeds
- Water overlap calc
- Terrain classification. Generally, you want to know, based in the geological history of the voxel, what material should be used. EOWBGroundSurfaceTypes lists all the terrain types there is, so this enchanter, based on more or less complex logic, categorizes all voxels. Implemented in UOWB_MarkTerrainTypes_Enchanter
Blueprint, C++, Editor, Runtime
Generally all the heavy stuff lives in C++, all the setup and top-level manipulations are exposed to the Blueprint. This is true for general-purpose code, like default errosion sequences and example terrains (introduced as Blueprints) as well as for Editor-specific code (most editor-related logic is implemented with blueprints).
So, most things you would want to customise/use are implemented as blueprints. All hardcore stuff exists as C++ only, thou C++ is quite clean and -organized the way that it is easy to understand and to use.
Runtime vs Editor
In fact, all Open World Bakery functionality (except for async execution, which is generally unavailable in Editor at a moment) is available both in runtime and in Editor. You can explore OpenWorldBakeryLandscapeBrush blueprint to see, how to work with Bakery in editor, and you can open example projects to see some examples of Bakery usage with different mesh providres.