Horizon mapping is a method of shadow mapping specific to height maps.
It can handle any angle between 0 and 90 degrees from the ground, as
long as know the horizontal direction in advance, by remembering only a
single angle (the "horizon angle" of the shadow map). More is explained
in common/src/msg/server.rs. We also remember the approximate height of
the largest occluder, to try to be able to generate soft shadows and
create a vertical position where the shadows can't go higher.
Additionally, map generation has been reworked. Instead of computing
everything from explicit samples, we pass in sampling functions that
return exactly what the map generator needs. This allows us to cleanly
separate the way we sample things like altitudes and colors from the map
generation process. We exploit this to generate maps *partially* on the
server (with colors and rivers, but not shading). We can then send the
partially completed map to the client, which can combine it with shadow
information to generate the final map. This is useful for two reasons:
first, it makes sure the client can apply shadow information by itself,
and second, it lets us pass the unshaded map for use with level of
detail functionality.
For similar reasons, river generation is split
out into its own layer, but for now we opt to still generate rivers on
the server (since the river wire format is more complicated to compress
and may require some extra work to make sure we have enough precision to
draw rivers well enough for LoD).
Finally, the mostly ad-hoc lighting we were performing has been (mostly)
replaced with explicit Phong reflection shading (including specular
highlights). Regularizing this seems useful and helps clarify the
"meaning" of the various light intensities, and helps us keep a more
physically plausible basis. However, its interaction with soft shadows
is still imperfect, and it's not yet clear to me what we need to do to
turn this into something useful for LoD.
Currently it just always rotates towards the camera, but it wouldn't be
hard to create a config option that swaps out the rotation of the
indicator and the map.
With these changes, we can successfully open, map, and play maps thare
are 16x the size of a standard (1024 x 1024 chunk) map, 4x larger in
each direction.
Turned a lot of for loops into for_each loops, which should be easier
for LLVM to optimize currently. Also updated almost all the non-erosion
stuff in WorldGen to run in parallel (and take advantage of the cache,
in the case of TownGen), and hopefully improved performance somewhat for
chunk generation as well.
- soil production (currently disabled).
- debris flow erosion (combined with regular stream power law).
- flow computation using multiple receivers.
- filling strategy during drainage network calculations.
Also tweaks a variety of other aspects of erosion.