Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.66k stars 250 forks source link

Issues regarding getting terrain data #83

Closed slapin closed 4 years ago

slapin commented 4 years ago

Hi @Zylann, thank you for your great tool!

I need a few specific things so I ask you to pause for a bit and answer my poorly formed questions.

I create terrain for my game. Your smooth voxel terrain works great, but I need more.

  1. I need multiple materials/textures per voxel to implement less regular terrain pattern. Where should I look to do that?
  2. I implement road system and for that I need 2.1 get height information for road to match terrain so to be able to put city streets in there, so to avoid too rough areas. 2.2 be able to smooth-out terrain to match road (not penetrate it).
  3. I need water bodies around the terrain so that they do not mess with other things and allow swimming and diving into and supporting boats and other water vehicles. How can I make these in a way friendly with your terrain system?
  4. I need to place grass and trees and little stones/rocks and other debris on the surface, what would be best approach?
  5. If terrain is used in "endless" mode, is it possible to somehow offset terrain data to have shifting origin right?
  6. Do you plan to add navigation system based on detour to build realtime navmeshes for best terrain navigation?
Zylann commented 4 years ago
  1. voxels are transformed into meshes. Smooth meshes are currently assigned only one material because they are generated with only one surface. If you want more than just a procedural shader for visual purposes, you may modify the mesher you are using to take into account a new channel you would call "MATERIAL" (or re-use the existing TYPE channel) so you can tell which material each voxel has. Then you have two options:

    • Either you use a splat/texarray shader and then all you need is to populate the COLOR attributes of vertices with the material ID, which you use in shader
    • Or you modify the mesher even further so that it generates two different surfaces, each can then have their own full material. However they won't ever blend. This is a similar problem as https://github.com/Zylann/godot_voxel/issues/69
  2. Roads
    2.1 If you generate your terrain as a heightmap, then you have the heightmap information already. This is a voxel module, it doesn't make this assumption, so that's data you need to pass yourself through your system. Note that the VoxelStreamImage is not really meant for production, it's only a quick example to start from, you'll want to write your own almost every time, for those reasons. I'm aware that there could be an improvement to the API so that you have a callback when blocks get added/removed to the terrain, but you could already generate roads and other objects using a separate system, provided they use the same generation data (i.e both systems would know the heightmap).

    2.2 This is something you need to figure out as well. Generate the SDF channel accordingly, in prevision for a road to go there. Note that with LOD this is quite hard to guarantee, I don't know a magic solution about it.

  3. I don't have a silver bullet for this either. You need to know what you want, precisely. At the very least it can be a simple plane, or cube, placed in an area you know is fit for it (since you generate it from heightmap, as I understood). If you consider terrain destruction then you might need something hinted in https://github.com/Zylann/godot_voxel/issues/69, so basically have a second layer of voxels, eventually with fluid physics as https://github.com/Zylann/godot_voxel/issues/70.

  4. I don't know. It could be batched additively into the terrain meshes or it could be added as multimesh as a post-meshing step (knowing material explained in 1 could help), or be generated from shaders directly (mesh shaders, geometry shaders?).

  5. It should not be hard to do. Currently the entire terrain (which extends Spatial) is fixed but it could be made to react to its transform, so all you'd have to do is move it.

  6. This is not really for this module to handle. It generates collisions so any generic system based on collision could use that information. At the very least you can write a system using the voxel grid anyways, which is accessible data.

Overall, some of this are things already reported, that could be added to the module to help accomplish them, and other things are up to you. I can't tell how long before I get to work on this (I'm currently doing a break from my Godot stuff), and I got other things to figure out myself (such as island detection, "non-terrain" voxel nodes and bugs to fix).

slapin commented 4 years ago

No rush, I was just asking as I more or less completed the road system and think about how I can make it work with voxel system having noise as main source but tweaking it for roads and buildings.

Thanks for your answers, it is more or less clear now. Would be nice to have some foliage aid though as parsing meshes is too expensive to be realistic and VoxelLodTerrain does not support raycasting, so kind of surface helper would be nice. Detour can help with this though which will need some heavy coding and I think an overkill in this case as the info should be available from voxel system (getting all voxels having open surface, i.e. voxel querying for attributes). Or at least voxel tagging with custom data would be nice too for example for fx (i.e. walking on sand surface should produce sand particles, walking on snow or mud should produce footprints, etc.) so having kind of quieyable database would be nice. Detour will be needed anyway to detect climbable areas and ledges and other surface characteristics but that is usually done in smaller scope than whole terrain chunk...

If that is soemthing which can be effectively implemented outside the module would be nice to know some idea. By the way your splat mapping idea - will it work with GLES2 renderer?

Zylann commented 4 years ago

VoxelLodTerrain does not support raycasting

It does if you have collision shapes, but it doesn't if all you have is voxel data. It's possible to implement, though. If you don't need high precision even a naive method can be easy enough.

By the way your splat mapping idea - will it work with GLES2 renderer?

I think so? But maybe not if you use a texture array (might be workable with an atlas).

slapin commented 4 years ago

About water - precisely I want to find a limited surface object which is a triangulatable contour of water surface which will be generated and area object which will add cube with underwater shader when camera is considered submerged. These come in various sizes because main source of height is noise. The reason to have water implemented this way is ability to modify geometry for boats to not have "water" inside them and simulate "proper" water physics.

TokisanGames commented 4 years ago

There are many methods to place objects, grass, trees, etc.

You could use a multimesh for some things.

Here's a method to add grass. https://www.youtube.com/watch?v=uMB3-g8v1B0

VoxelLodTerrain does not support raycasting

This used to be true but not for a few months. Where did you get this information? Did I leave this note in the docs somewhere? As long as you keep collision enabled, you can run a normal raycast. In fact, I think my fps_demo character uses a raycast collision shape.

You could have your world builder script use raycasts to place objects on the terrain using raycasts. Start at a Y above the noise height_start + height_range and shoot down with large distances, or repeat at intervals until you hit something. Then shoot all around to get an idea of the landscape around the hitpoint (i.e. slope).

Or you could drop objects from high up and just let the physics engine place them wherever they land. Trees have some logic to ensure they end upright.

slapin commented 4 years ago

Well, that would add unwanted visual artifacts. Also this does not solve cave floor placement. Also particle method (as well as multimesh) is costly on rendering for some reason and does not work on GLES2 renderer of Godot. Manual batching of grass into mesh works quite well but requires all coordinates at once, so my question would be about how to get all floor coordinates with normal facing up enough to consider these a floor. Would be nice to know that. As I understand that might belong to stream code, but have no idea about how I could use these effectively. Would be nice to know proper consistent architecture for this.

On Sat, Nov 9, 2019 at 11:59 PM Cory Petkovsek notifications@github.com wrote:

There are many methods to place objects, grass, trees, etc.

You could use a multimesh for some things.

Here's a method to add grass. https://www.youtube.com/watch?v=uMB3-g8v1B0

VoxelLodTerrain does not support raycasting

This used to be true but not for a few months. Where did you get this information? Did I leave this note in the docs somewhere? As long as you keep collision enabled, you can run a normal raycast. In fact, I think my fps_demo character uses a raycast collision shape.

You could have your world builder script use raycasts to place objects on the terrain using raycasts. Start at a Y above the noise height_start + height_range and shoot down with large distances, or repeat at intervals until you hit something. Then shoot all around to get an idea of the landscape around the hitpoint (i.e. slope).

Or you could drop objects from high up and just let the physics engine place them wherever they land. Trees have some logic to ensure they end upright.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Zylann/godot_voxel/issues/83?email_source=notifications&email_token=AAABPUZFF75IKONNCZRHV5TQS4QBVA5CNFSM4JLFATIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDUPCII#issuecomment-552136993, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABPU747L7YPFCLTW6EOGTQS4QBVANCNFSM4JLFATIA .

Zylann commented 4 years ago

I'll close this for now because although some things are relevant, subject is too broad / lists many different things that should be their own issue.

slapin commented 4 years ago

won't you forget about relevant things like that?

On Sun, Jan 12, 2020 at 12:41 AM Marc notifications@github.com wrote:

Closed #83.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.