Repository: godot
Issue: [TRACKER] Making terrains
Labels: bug,enhancement,topic:editor,topic:plugin,tracker,topic:3d

I found a number of issues about making terrains in Godot, be it heightmap, voxels, an engine module or a plugin, so I thought I would make a tracker to list them all:

Engine limitations:
(some might be "closed as fixed" but are still actually open in a different issue, or have been closed in favor of another issue that doesnt exactly match the problem; need to take the time to update this list)

- [x] #9544 : need to be able to set custom bounding box per mesh instances, to unlock the ability to do shader-displaced heightmaps and reuse mesh configurations ; the lack of this feature produces culling glitches

- [x] #9571 : need to be able to update a texture partially. Editing huge textures on the CPU makes terrain editing unbearable on huge sizes (although GPU painting can be investigated to some extent).

- [ ] #7786 : needs ability to do custom LoD that works in multiple viewports (currently limited to _process on a single viewport), so that the renderer doesn't chugs on culling and drawing the whole landscape, especially on split-screen games. Custom, because LOD on a terrain is often different from LOD on a single model, mainly due to the constraint of keeping the terrain watertight with seams, and that quadtrees may be used instead of chunks of the same size.

- [x] #8994, #5624 : scenes and resources saved even without changes, with a terrain it can freeze the editor for seconds and become very annoying. I disabled Ctrl+S saving the scene for that reason.

- [x] #6869 : LoD must update differently in editor because camera is not easily available. Current workaround is to use the camera provided in `_forward_spatial_input`. #6869 was mentionned to solve this but it actually doesn't change the situation, so I'm still using the same workaround to make it work.

- [x] HeightmapShape would be nice for efficient collisions, because mesh colliders are resource-hungry (althought they work decently if limited to a small region) --> would be solved by the HeightmapShape coming in the Bullet PR #10013

- [ ] needs custom streamed resource so that a terrain doesn't have to be fully loaded in memory (only required lods around player), speeding loading times (the engine probably supports it already though, for sound). Custom loaders or custom resources will help to solve this.

- [ ] [tbd] : Editor: add an undo history memory limit, or use file caching, because terrain edition generates a lot of undo memory in general. It can be worked around by storing "handle objects" or IDs in the undo methods instead of the data directly, which map to data inside temporary archive files, effectively storing the action's data on disk rather than memory. But it has to be implemented for every feature.

- [x] #9008 : needs texture arrays / 3D texture support in shaders, for efficient texture painting / terrain shaders. @karroffel worked on that for 3.1.

- [x] #10255 : need 2D blending mode(s) that treat alpha like a regular channel, so it can be used for more general purpose, such as GPU painting of splatmaps or other 4-channel data maps terrains can use. (which is way faster than doing it in C++ on the CPU)

- [ ] tbd: need more control over offscreen rendering, mainly custom image formats when making viewports and ability to make them render on demand (#16828), so they can be used more efficiently for GPU-accelerated terrain edition (example: erosion needs to use directional blur over multiple passes, for which you currently have to wait for every frame instead of telling the renderer to do them all at once). Using current viewport forces usage of nodes, waiting frames, and using RGBA16, which eats a lot of memory and bandwidth in some cases, or terribly lack of precision in other cases. Using texture channels differently is an alternative, however it complexifies code a bit, and forces copying the entire shaders just to change a few lines of lookup because Godot doesn't have #17303

- [ ] #17683 : improve resource usage when drawing big textures for the first time, as saving a terrain writes them all to the project, which causes re-import AND reconversion on draw, which can cause computer to freeze.

- [ ] tbd: integrate with navmesh generation. Currently navmeshes are generated using meshes, but a heightmap using a quad tree or streaming for LOD will never have them all present at full precision. My plugin recently made its generated collider available in the editor, but the navmesh generator is not using it, and probably can't because it's still a grid instead of a mesh.

- [ ] tbd: integrate with lightmap baking. Currently Godot only takes static meshes into account but a large heightmap using a quad tree or streaming for LOD will never have them all present at full precision, and they are displaced in shaders anyways. This one could be very hard to solve without either deeply integrate the terrain, rewriting a plugin lightmap baker from scratch, or change the baker so that it uses a GPU technique taking unshaded rendering result into account (but streaming would still come in the way).

User requests:
- #3616, #8124, #8254, #4304
In several occurences my GDScript plugin was mentionned. I once switched it to C++, then back to GDScript because it seemed to work well enough and it allowed people to use it more easily. Unfortunately it still is a bit slow in some areas, and mostly suffers from not being easy to integrate with the engine.
A 3D terrain is quite a beast to have in game engines because very often (if not always), other components of the engine might need to interact with the terrain in many different ways.

Issue tracker on my terrain plugin:
https://github.com/Zylann/godot_heightmap_native_plugin/issues

Won't do for now **but to consider for Vulkan**:
- ~~#9134 : needs 2 additional Vector4 vertex attributes for texturing (weights and indices), in order to exploit texture arrays. The current workaround is to use UV2, COLOR or BONE WEIGHT attributes, but it limits available attributes a lot.~~
- ~~[tbd] : indirect drawing of meshes (glDrawIndirect on renderer side, also supported in GLES3) to draw multiple subsets of mesh arrays so that we can swap LoDs really fast and reduce the amount of draw calls for all chunks of the terrain. _This also gives the opportunity to bake chunks for good, to a point they don't need any remeshing as lods update_ (current method has an exploding number of remeshing)~~ (not in GLES3 core... https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawElementsIndirect.xhtml)
- #10817 Tessellation shaders, so that we reduce mesh data while being able to dynamically increase resolution to smooth near ground