-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Terrain #6121
Comments
I hope for a voxel terrain generation to be implemented in Godot someday. Features that I'd love to see in that case:
|
It would be most excellent if you could conjure some way to go beyond the horizontal-plane. Imagine caves, or a curved landscape (say a mini planet). Imagine games with real 3d; underwater and space. Also, for ultimate terrain freedom, please have a look at what Zylann has been doing with voxels. That could be a fantastic start: https://github.com/Zylann/godot_voxel |
Thanks. I would recommend giving possibility to customize/replace shaders. For the foliage I like to modulate albedo in some random way. Also, maybe there should be a possibility to set color/custom data for multimeshes? If possible, the terrain should have uv2s and should work with LightmapGI. BTW: would get_bake_bmeshes() be part of the official interface? It works very well and I'd like to rely on it in my addons. |
Another interesting feature could be tiling textures shuffleing. It could be some kind of a mask with randomized texture tiles grid cell borders and tile rotation to make terrain look more natural. |
There's an interesting section about different terrain editors in this GDC talk from 2016: While Unreal/Unity both have nifty terrain editors, they're missing a level of fine-control that something like Hammer allows. There's no way to do overhangs or cave-like setups with those types of terrain editors. Which means they all have to be authored by artists instead. It would be cool to have terrain that's actually more versatile than anything else available. |
#445 should probably be closed, shouldn't it? |
Custom shaders with layer painting Edit 1: |
It would be interesting to have the possibility to edit the terrain in runtime. This would be useful for creating procedural worlds or gameplay elements that require deformation like craters. |
I think that something that could help terrain, look better by default without uv use of shaders, is the ability to rotate the textures randomly to break seams . Something kinda like the technique roblox used to break seams, called organic patterm or prob by adding by default a noise texture to the terrain texture to break tiling. |
Added some FAQ regarding many of the points raised here. |
I'd like very much to argue against the comments trying to push for a voxel solution. While voxels are cool, they are definitely more niche than a heightmap solution. If you are making a game with a voxel terrain that is basically the defining feature of your game and probably is part of your gameplay, whereas heightmap terrains are simply useful for world building a ton of 3d game types. EDIT: EDIT 2: |
BaseMaterial3D proximity fade can be used to achieve this. However, to improve performance and avoid transparency sorting issues, we should add a mode that makes proximity fade use dithering instead of forcing alpha blending on the material (or make it use dithering unless the material is already using alpha blending).
As an optimization, it might be worth trying biplanar mapping. |
I don't think you could proximity fade without rendering to the transparent render path. That's why I suggested the depth offset dithering thing instead. But I don't know if that only works in a deferred renderer. |
I've just tried to replace alpha blending with dithering and can confirm it still goes through the transparent pipeline, likely because it has to read diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index d5c3f7730b..3bddbeda54 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1249,7 +1249,13 @@ void BaseMaterial3D::_update_shader() {
code += " float depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n";
code += " vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex,1.0);\n";
code += " world_pos.xyz/=world_pos.w;\n";
- code += " ALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
+ // Use interleaved gradient noise, which is fast but still looks good.
+ code += " const vec3 magic2 = vec3(0.06711056f, 0.00583715f, 52.9829189f);";
+ code += " float fade2 = clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
+ // Use a hard cap to prevent a few stray pixels from remaining when past the fade-out distance.
+ code += " if (fade2 < 0.001 || fade2 < fract(magic2.z * fract(dot(FRAGCOORD.xy, magic2.xy)))) {\n";
+ code += " discard;\n";
+ code += " }\n";
}
if (distance_fade != DISTANCE_FADE_DISABLED) {
|
@Calinou For a while I thought we should have an extra render pass called decal pass where you can do those things and still remain in opaque pass. This could be used to render the terrain (after everything else) and do a bit of blending into objects that go into the ground. |
Will there be Terrain Partitioning support for larger scenes to ease the load on both the editor and runtime? |
@MaxIsJoe Godot can just handle this with the scene system transparently, no need to implement that kind of things that are more unity/unreal design workarounds. |
Why was this created instead of continuing discussion on the most popular one? As for the world partition stuff - it really is pretty straight forward to implement in Godot with the scene system. I did it long before WP was even announced in UE5. |
@Duroxxigar this is a proposal with a specific implementation, its easier to discuss details of it here. Can link to it from the other one if you wish. |
I think not allowing custom shaders would be quite limiting for a modern terrain system. Shaders allow for several possibilities:
I would suggest having the
|
Terrain stiching: Just split the world in smaller patches and force each patch to share the edge pixels. Terrain spawning: I have been experimenting for porting my Terrain Module and using simple mesh instances in Vulkan is fast enough as long as they use the same mesh resource (lod morphing should be implemented in the vertex shader) for GLES renderer it should be capable of fall back into multimeshes. Biomes could be made following the Horizon Zero Down presentation on this topic available at their webpage. Here Compute shader should come very handy to speed |
@mrtripie You should be able to have a custom shader for the whole terrain to do the things you mention. What is likely not possible is custom shaders for each terrain paint material. |
@ozzr I prefer not go the terrain stitching route and just allow infinite terrain editing. Its just a lot more user friendly to me. |
Good point, however I find that a Unity like Terrain should be more Godot friendly |
Horizon Zero Down GDC presentation this is the presentation I was talking earlier for Biomes |
@ozzr I think with the right hooks it should be possible to generate procedural content to do something like this. |
I would imagine that foliage painting would potentially be a performance issue if a user attempts to paint hundreds of thousands of grass meshes in a location. Given this, I would imagine that the current MultiMeshInstance3D node would potentially need to be more flexible and provide more features similar to the Scatter plugin? (ie https://github.com/HungryProton/scatter) Update: I re-read the proposal and if I understand this correctly, painting anything will index the foliage instance for use in a multimesh instance per terrain chunk? Maybe my concern is non-existent? Update 2: Also, if entering something like a Dungeon or a Cave from the terrain, would toggling the visibility on the terrain or using an OccluderInstance be enough to prevent the terrain from rendering? Would there need to be alternate methods of doing this for performance reasons, like an AABB on the terrain or individual terrain chunk / region? |
Just my 2cents on the subject. First, interesting reading through many peoples reactions and for me this only underlines more why it is so important that a terrain module becomes a plugin. The last thing we want is a bloated terrain module that supports every possible terrain system that is out there. The proposal here is for a terrain module based on height maps as it is one of the most common systems founds in large / open world games. It strikes a good balance between performance and a usable terrain that can be further dressed up with meshes. Second, on the proposal itself, I'm missing a few key features that I think should be added in. PhysicsIn order for the player (and NPCs) to interact with the terrain, there should be a tie in to the physics engine. As heightmap textures are streamed in, these textures should be converted to heightmap data while still in CPU memory that the terrain system can submit to the physics server. The terrain system can manage this fully so the terrain is automatically managed as a static collider. A question here is what to do with terrain that isn't loaded, a persistent NPC might run off into the distance as part of a quest and fall through the map when it runs past what is loaded. Another question here is whether to incorporate collisions for bigger foliage like trees. Personally I actually believe that foliage systems are separate from the terrain system but should be able to access terrain data for placement. Scene managementAs the terrain module loads in chunks, or expels chunks of terrain that are far enough away, there should be some mechanism to hook into this, be it through emitted signals or some further automation, to load in scenes that contain the rest of the game data related to that chunk of the map. Especially on open world games you don't want to keep the whole worlds worth of buildings, NPCs, and other objects in memory. You're loading those alongside new chunks of terrain. Stream optimizationThis may be overkill for our needs and possibly not as much a problem as it was in yesteryears, especially with modern PCs and consoles having plenty of disk space and copying game data onto harddrives instead of reading them from source media. But if terrain data is stored on fixed media, say Bluray, the maximum data throughput and random access costs can become a hindering factor to getting terrain data streamed into the game fast enough. Many terrain systems deal with this by duplicating terrain data in various reordered ways to ensure optimal loading no matter the direction of movement. Space is cheap in this case. Best practice guidesThis I think will come naturally when a terrain module becomes widely available but there are a number of common pitfalls and issues around large open world games that we may want to per-emptively catch and educate people about. An example of this is the aforementioned NPCs falling off the map because a quest line sends them into an area of the map no longer loaded. Another is dealing with NPC persistence as chunks of the world are unloaded and reloaded. |
Interesting. Can GDExtensions expose stuff to GDScript? I have a plugin ive been working on that generates an entire heightmap all at once, after compositing "stamps" together to generate a heightmap. How would this work? |
If you want to generate your heightmap with some function you can also do it now even in gdscript But I don't understand the second part of your question if you can explain me more |
My plugin creates a heightmap. How it does it isn't important. Would I be able to set the entire heightmap all at once and have it update? Can I also update specific regions? |
Yes off course you can do, for x in range(0,1025):
for y in range(0,1025):
var value = generate_value_with_your_plugin_base_on_x_y
set_height_by_pixel(x,y,value) But this will take sometimes, especially if your terrain is big, if you update a small region there is no problem |
perhaps that would be useful to include with the API? |
Thanks, for the reply, the terrain size is the same as the one from your tutorial though following it step by step and downloading the RAW link, and it has sdfgi off( because my igpu can't handle it , at least until they rework it maybe), and ye it can help that. |
Thanks to you Saul2022 that you test my terrain |
The C++ based editable terrain system @outobugi and I have been working on for the last several months has been released. MIT License. Still in alpha, but stable. We're starting to incorporate it into our game, Out of the Ashes. https://github.com/TokisanGames/Terrain3D Overview on youtube: https://www.youtube.com/watch?v=Aj9vWIEaFXg So we don't clutter this thread with too many messages about any specific system, you can review issues and documentation on our repository page. Or you can join my discord server. https://tokisan.com/discord |
Tested it out and works fine for my igpu, though there´s some performance degradation sometimes when sculpting and stays like that until i dissable the sculp brush. I think it could be good to move the conversation to a discord server if you want to create it for your terrain, so more people may know about it, and it could bloat bless this chat. |
Hello Dear Saul2022 |
Grass Demo, It is not on Github yet but you can watch that on Youtube: |
Hi, everyone! this is my landscape system taking its final shape. I already started working on the Editor itself, and some other quality nodes to modify the landscape. I am using clip-maps for streaming the textures data, and the collision and quad-tree elevation limits are either prebaked on save or generated at runtime and stored at the user folder as custom files and then streamed on demand. The system makes heavy use of multi-threading. Concerns
Questions
|
The entire MultiMesh (or CPUParticles3D) switches LODs at the same time (all use the same LOD level), but individual instances can't use different LOD levels. |
One issue I'm not sure has been brought up here is that making Terrain an official plugin might not be feasible due to the of time the team has to work on/pay attention to it. It's been 1.5 years as of the time of writing since this proposal and as far as I'm aware we still don't have the plugin reduzio mentions. Even if one was created, would adequate time be dedicated to adding features, fixing bugs and reviewing/accepting PRs on this separate plugin compared to one built in to Godot? Third party addons are also not the answer here. They don't get the support a first-class feature gets, and they have too many issues with newer versions of Godot - for example the most popular current addon is Terrain3D which doesn't work correctly in the latest Godot Beta and as far as I'm aware requires recompiling for each new version of Godot released which almost no-one knows how to do. Terrain is clearly one of the most requested features for 3D. It's brought up in literally every 'What are we missing?' thread. Yes it's a higher level feature and yes, there's no one implementation that can cover literally every use case, however there is an implementation that can cover the majority of use cases, and anything not covered can then have an addon made for it later. Adding terrain to core is a better solution IMO to what we're doing at the moment which is nothing. |
Juan has made it clear multiple times that he doesn't want Terrain built in to Godot. This PR was a way to collect thoughts for a plugin implementation by someone, not a plan for him implementing a system. There are at least 5 good terrain plugins available for Godot, plus the built in gridmap system and other solutions, that provide enough infrastructure to meet the needs of most developers.
They are the only answer. Even if you were to become a core developer intending to be the one to implement and maintain a core terrain system, as stated Juan and Co don't want it.
This I partially agree with and have expressed. However, the core team has been good about providing help on our tickets and in the developer chat. We have found workarounds for deal breaking issues, like saved resource files can't be larger than 1gb. And there has been nothing stopping us from contributing fixes or adjustments to the engine or GDExtension except time or need. As a plugin developer, I don't have any major issues or complaints.
I don't intend to sound rude, but this is frankly a misunderstanding of beta status. It is an unreasonable expectation that 3rd party plugins will always support every unstable version of Godot. The core developers are changing the engine all the time, and breaking things. It is a moving target. There are still months of development for Godot 4.3 to go through 3-6 betas, then 2-4 RCs. The open source nature allows experienced developers to use development versions, with the expectation that things are not supported, may require self-support, and may not even work at all. They are not intended for use in production or by inexperienced developers who should only be using stable versions of the engine and plugins.
You are very mistaken. Terrain3D has worked with forward stable versions since 4.1 last year, due to extended features in GDExtension. Our CI system builds Terrain3D on every push, providing prebuilt binaries for stable and development versions. And we have many developers who are building from source, by following our well documented process. Occasionally the engine devs break things in future versions which should be obvious that our older version cannot support without a change. Those changes are sometimes pushed into the stable version, but usually put into our development version. Our stable version works fine with the stable version of Godot. That is the only scenario newer devs should be using until they become capable of self-support. I can use the latest development version of Terrain3D (available as precompiled nightly builds) with the stable or latest Godot beta just fine. Though the latter is still not supported for the reasons listed.
In the past, it was the most missing, most needed feature. That's why Roope and I built Terrain3D. Now with 5+ systems, any future mention in "what are we missing" threads is frankly due to lack of knowledge of the terrain ecosystem. The solution is sharing and improving the existing systems not waiting for over worked core devs to write a 7th system. Here's the full list of Terrain Systems for Godot 4 that I'm aware of:
Plus there are partial solutions such as:
So I hope this clears up some misunderstandings about the Godot terrain ecosystem and our plugin specifically. @reduz Unless you plan to change your mind and create a native terrain system, I suggest that the 5+ available solutions have adequately accomplished this proposal and perhaps it's time to close this thread. The only thing not really covered is any "official designation" that you mentioned. I assume that requires more internal discussion and a separate proposal if public feedback is desired. Perhaps in lieu of an "official status" the above information should find its way to a "recommended solutions" page in the documentation or website that lists known working terrain, rivers, oceans, skies, roads, and other commonly needed systems. |
@TokisanGames I agree that the terrain system is too big to be included in core Godot engine, but we probably don't need 5 solutions for the same functionality. Also, state-of-art terrain systems utilize compute shaders to archive faster speed, whereas most existing Godot terrain plugins haven't caught up with it yet. It might be beneficial if Godot can dedicate an official terrain plugin so that everyone concerned can pool their efforts onto developing one single terrain plugin. |
@rossbridger Compute is entirely unnecessary for runtime as it's not a rendering pipeline. It is beneficial only for editing, and even then, only for large sections >200m, or for complex options like smoothing and erosion. It also excludes all OpenGL users. We will support some sort of GPU editing in the future. Zylann's HTerrain already supports GPU editing via viewports. At runtime, our terrain already runs on the GPU and we are regularly increasing features and speed. In the open source community, people contribute where they want. We have a pretty good team of contributors with some amazing MVPs. |
Since your implementation uses geometry clipmap, that part is true in your case. However, more recent terrain system like Unity's CBT and Call of Duty's terrain system use compute shaders to update its runtime terrain data structure per frame. I was looking at bevy engine's terrain the other day, it also uses compute shaders for runtime steps like quadtree subdivision and frustum culling. I think it might be superior to all existing terrain systems in Godot so it would be nice if someone can port it to Godot and do a benchmark.
If someone is developing a game targeting compatibility profile, it's very unlikely it needs a massive terrain system anyway. |
I wish some comm features(like terrain, behavior tree etc) can be core. not addons. or, can we mark some addons as offical addons? eg, where was some terrain addons, and like test some. very addon has something i like, and some miss feature thad i need, i don't know which one i should select, and i don't want make report for every addon's author. and, i'm afraid some day the addon that i selected stop update. if where was a offical addon or be core. i'm clear to select and report bugs. |
I get the point though for this terrain the cost is not really on rendering the terrain thx to geo clipmap, but more on the base shader cost as it lets have like 32 textures and 32 foliages with high distances and good lods(that in my case i noticed almost no pop in). For the shader there are already feature request like runtime virtual textures and normal map bake in play mode so it simplifies the shader and the performance gets better. |
If you've already have that many addons you would need a setting like opt-in to disable a built-in terrain system - especially if you want to use terrain addons. And what about mobile? Can Godot Engine for Android handle a built-in terrain system - especially cheap Android devices? |
It can as it works on both forward+ and mobile renderer. |
While I understand why putting a powerful terrain feature into core is unwanted, I think we also have a bit of an XY problem here. I think for most use cases, all that users really need is a basic terrain mesh, and to make simple adjustments to it in a WYSIWYG way - namely basic sculpting and texture (material) painting. Making adjustments externally, without a reference to the placement of objects in a scene, is just too imprecise and annoying for any real work. Hybrid workflows where some assets are placed from Blender and some in the engine don't really solve this issue. So what I'm thinking of is something like
Since this would be a regular mesh rather than some plugin construct, it would integrate well with existing features such as:
I know this for a fact - I implemented this with a regular While I believe this would cover most use cases, I'm not sure how big of a feature such an editor would be, and by extension - if it would fit in core. P.S. I also used this method with a heightmap, but this method is better kept for more advanced terrains like the plugins mentioned earlier. Generating heightmaps from Blender is a bit scuffed, and making a mesh displaced with a heightmap shader match the collision mesh without dynamic subdivision is kinda impossible. Also the collider had to be manually updated after each heightmap import, which wasn't great. Footnotes
|
I just took another look at bevy's terrain system, and I noticed that it doesn't generate any mesh data, but it feeds its quadtree data into the vertex shader as SSBO and computes vertices directly on the shader. This can be a huge memory optimization but it seems Godot doesn't support SSBO yet. |
Vertexless meshes certainly do work in Godot. I haven't implemented it in Terrain3D yet, but it's on the list for both terrain and foliage meshes. |
Rendering primitives involving little/no vertex buffers is something I'm experimenting in a non-Godot project (not heightmap terrain, but similar needs), and it's such a big win for my project I'm keeping with it. Unfortunately Godot might still lack an optimization feature for doing the same thing I do. I should probably open a proposal, but to summarize: When coupled with the ability to read from an SSBO in the vertex shader, it allows to save a lot of memory by having more control on how geometry is provided. That might not be feasible in the compatibility renderer though. Using a texture is also possible when SSBO is not available, but is inconvenient and probably slower. |
@TokisanGames The technical difficulty here is passing an SSBO to vertex shader, which is not supported by gdshader (working with RenderingServer directly and writing raw GLSL might work, but I haven't seen anyone ever done that, and at this point one probably can use VisualInstance3D or GeometryInstance3D directly). |
Describe the project you are working on
Godot
Describe the problem or limitation you are having in your project
Godot users want terrain. Terrain will not be added to Godot, because to make it properly it requires to be a high level feature.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
The idea is to create an official terrain plugin that we will maintain and which can be easily downloaded from the asset library.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This would be an official terrain plugin using GDExtension. This is the list of how it would probably work and the list of features it will have.
Terrain Materials
For modern terrain rendering, texture arrays must be used. This ensures quick access to all textures needed to render terrain. For creating these textures, we would need something similar to how atlas textures work:
Terrain Rendering
Terrain should utilize a standard heightmap with levels of detail allowing to stream regions in and out. This can also be done with a texture array containing the levels in powers of 2 and using standard clipmaps (that are read in the vertex shader) which can fade into higher mip levels to avoid popping.
The shader works more or less like this:
Up to a certain distance (1km ? 2 km?) the shader reads the "material index" texture, which is basically a 16 bits 4096 x 4096 (as example, can be changed) containing material indices.
The 4 materials to blend are obtained, materials are read and blended (most likely using triplanar).
Beyond that distance, to avoid aliasing in the algorithm above, the terrain is blended into low resolution albedo+e, metallic textures that are read directly.
As an aditional step it should also be possible to store a color map to modulate the material color and generate some extra variation.
Terrain Shader
While setting a different shader for every terrain painting material will not be possible (as drawing happens all at once). It should be possible to customize the shader used for drawing. This would allow games to customize a good amount of things:
But of course, this is up to each programmer to implement.
Foliage
Foliage (grass, rocks, etc) happens at the same resolution as the terrain, storing a foliage material index (or zero if no foliage).
Upon load of a region, instancing of foliage is done with a multimesh generated on the fly and instantiated with a visibilily LOD. Foliage will also be modulated by the terrain modulation color.
Decorations
Decorations (trees, larger rocks and other chunks of terrain) are also a library of meshes that can be manually placed. They are condensed into mutimeshes at the time of drawing for speed up. The terrain system may also decide to generate impostors for groups of decorations if if intended to be seen from very far away.
Scenes
Scenes are instantiated upon proximity (the scene can determine its proximity).
Terrain Storage
The terrain can be stored directly as high resolution material index regions + mipmaps, so only what is needed is streamed-in. Foliage indices can also be saved as well as decoration indices or LODs for different draw distances.
Terrain Editing
Terrain editing can happen in a dedicated editor for the terrain node. The following should be editable directly:
Holes
The regular (simpler) way to do holes in terrain is to force an INF into one of the vertices. This kills all triangle associated, but will not generally play great with clipmaps, so this needs to be done in a way where only allowed to happen until a certain distance, then the hole pops back in. The hole often has to be "decorated" with geometry so you don't see the clipped triangles.
Procedural generation
To implement procedural generation, it should be possible to override, intercept or complement the functions that fetch data from disk in order to create procedural data. This should help pregenerate all or partial content based on code rather than having to place everything manually if working on a large game.
FAQ:
Q: How do I define the size of the terrain?
A: Ideally you shouldn't, you simply determine a max view distance and the terrain is infinite (it lifts data if it can find it, otherwise its generates terrain at 0m. You can keep editing it as you move around.
Q: Can I do terrain overhangs with this system?
A: No, most games do this by adding extra geometry (like having some large overhang rock and reusing it all over the place). To do this properly, you would probably need a voxel terrain editor, which has different tradeoffs.
Q: Can I do caves with this system?
A: Not with the terrain, but holes can be used to add a cave, which can be modelled in 3D or done with something like GridMap.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No
Is there a reason why this should be core and not an add-on in the asset library?
It will be an official add-on.
The text was updated successfully, but these errors were encountered: