Might is Right, the game

I’ve been working on something interesting for a week or so. Meep game engine has a pretty comprehensive terrain system. It works with height maps and build geometry in rectangular chunks inside a WebWorker, asynchronously, when said chunk first appears inside a view frustum of an active camera.

Here’s a preview with each chunk having different color:

That has worked for me for all these years, but as it happens - there’s an invetable defect that I’m sure many of you have seen before in lots of games - stretching of textures at sharp angles. The cause of that is the UV map, the map is build uniformly, it’s basically a UV map for a planar grid.

I’ve written a UV optimizer, to fix some of that stretching, it re-distributes UVs at each vertex based on the amount of tension, basically treating the UV map as a some kind of stretchy super-heavy fabric that is allowed to move about to equalize the tension at any given point. There will be some stretch, that’s inevitable, but it’s no longer localized, instead it propagates across the entire UV map.

The solver is iterative, it finds a set of connecting edges for every vertex and then equalizes the tension across those edges by moving the UV coordinate for that vertex.

Here’s what that looks like in action for 7 iterations:

Here’s 1000:

I went with 21 iterations for now, it’s good enough and still dirt-cheap to compute:

Here is another scene at 21 iterations for comparison:
Before:


After:

Here’s with just the terrain and mountains in checker grid for clarity:
Before:


After(21 iterations):

It’s not exactly what I thought it would look like when I set out to write this thing, but I kind of like it.

The main point for me is that it reduces stretching and only adds 1-2ms of build time per tile, which is entirely reasonable for me.

Anyone know of other ways to reduce UV stretching?

4 Likes