Addon: Just Load My Terrain

I am developing a plugin for Godot 4.4 that generates terrain meshes using heightmaps. The generated terrain is composed of chunks, with each chunk being a MeshInstance3D. Each chunk also includes LODS (up to 6), a collider for physics and an Occluder3D for occlusion culling. I need to optimize the plugin for faster generation of very high-poly terrain, as it currently takes 1 minute to generate a terrain with 8 million polygons (the current maximum supported by my plugin).

The plugin will feature:

  1. Selectable Terrain Sizes
  2. Selectable Terrain Resolution (up to 8 million polygons)
  3. Selectable Terrain Chunks (up to 225 chunks) - better for occlusion culling and distance fading
  4. Support for using a colormap for the diffuse texture (high resolution recommended, 4K+)

To-Do List:

  1. Optimize the mesh generation for higher resolution terrains (currently limited to 8 million polygons)
    2. Implement a terrain smoothing option to fix rugged terrain [Done]
  2. Improve material support for more complex texturing
8 Likes

Update: The addon it’s nearly complete. The plugin generates terrain divided into chunks, with each chunk having LODs and a collision mesh. The collision mesh is generated from the same heightmap but at half the resolution (1/4 of the polygon count of the terrain mesh). This approach seems sufficient for an optimized collision mesh, as the default HeightmapMesh has a significantly higher polygon count, so I created a custom mesh instead. Each chunk also includes an Occluder3D for occlusion culling, though currently, I’ve disabled it to focus on displaying only the collision mesh.

One of the main challenges I encountered was ensuring that the heightmap resolution (a power of two) aligned with the number of chunks. Since the heightmap resolution must be both a power of two and divisible by the number of chunks, I resolved this by upscaling the heightmap to the nearest size meeting these requirements.

Another issue arose during chunk generation, where iterating over the heightmap size by chunk size required heightmap_size - 1 to avoid exceeding index limits. This, however, resulted in a heightmap size that wasn’t a power of two or divisible by the number of chunks, causing missing polygons along the borders of the final chunk rows.

I resolved this by adding an extra row of pixels to the heightmap, making the heightmap size size + 1. This ensures the heightmap size is always a power of two and divisible by the number of chunks, allowing the collision mesh to align perfectly with the terrain mesh.

I’m also considering further optimization: instead of evenly distributing the collision mesh polygons, I could analyze flat areas and replace them with larger quads. This approach could significantly reduce the polygon count.

6 Likes

Your program looks great! It required a lot of work and knowledge. I hope you get to the point you plan :slight_smile:

3 Likes

Yoooo thats awesome

2 Likes

The creation of the mesh from the heightmap wasn’t particularly difficult since there are plenty of example codes available in other programming languages (and the logic remains the same). The main challenges I faced were aligning the collision mesh and occluder mesh with the chunks. The collision mesh is at half resolution, and the occluders are at quarter resolution, meaning they all need to follow a power-of-two rule. Otherwise, the chunks won’t align properly with the heightmap. To solve this, I implemented a verification step that adjusts the heightmap resolution by increments of 1 until all three resolutions align. Additionally, the chunk size must be an integer, ensuring that the heightmap resolution, collision resolution, occluder resolution, and chunk size are all integers and divisible by one another.

Currently, I’m working on implementing Perlin noise and FFT-based heightmap generation, along with texture generation through shaders, to make the add-on more flexible and not reliant on pre-made heightmaps or colormaps. For now, I’m using the last free version of L3DT Pro to generate the maps.

Additionally, I plan to implement road generation using a texture mask. The idea is to allow users to draw roads directly over the heightmap using a mask layer, then utilize this mask to generate roads that naturally follow the terrain. This would greatly enhance the versatility of the add-on and open up new possibilities for terrain design.

I am making all this for my racing game (mobile) so the terrain needs to be very optimized!

1 Like