TokisanGames / Terrain3D

A high performance, editable terrain system for Godot 4.
MIT License
2.04k stars 115 forks source link

Water System #298

Open anandbarai09 opened 8 months ago

anandbarai09 commented 8 months ago

Description

We can create a shader for ocean and then set it in WorldBackground property in Terrian3DMaterial section. And make thing float with some lines of code as shown in the video. https://youtu.be/_R2KDcAp1YQ?si=A2o_jcG4XJmZJEx4

OR

Make a way to create custom WorldBackground shader so user can implement this by their own.

This would be helpful to create an Islands.

TokisanGames commented 8 months ago

An ocean can currently be implemented separately and independent of Terrain3D.

World background is just a shader, so a user could already implement it on their own using the Terrain3D mesh.

If we implement an ocean shader in this repo, water should be a separate clipmap layer, and its location paintable so it can be a lake, but that's a ways off.

anandbarai09 commented 8 months ago

I Agree with you but I mean to add a feature like the shader override in Terrian3DMaterial. This would be helpful to quickly switch with different World Background

anandbarai09 commented 8 months ago

An ocean can currently be implemented separately and independent of Terrain3D.

World background is just a shader, so a user could already implement it on their own using the Terrain3D mesh.

If we implement an ocean shader in this repo, water should be a separate clipmap layer, and its location paintable so it can be a lake, but that's a ways off.

I would like to make a ocean system addon, so any idea how to implement??

TokisanGames commented 8 months ago

I would like to make a ocean system addon, so any idea how to implement??

Do you want to add an ocean to your game or do you want to make a PR for Terrain3D to build in an ocean?

If the first, you don't need to modify terrain3d or the shader at all. Just make a large plane node with the water shader that overlaps Terrain3D, then you can set our worldbackground to none. The water node will intersect with the terrain at every point on every curve. There will be some redundant meshes but it's easy to implement.

If you want to make a PR, then you should do what I said in my first comment.

Putting the oceanshader on the worldbackground flat mesh is going to be challenging to do. You'll run into problems blending with the rest of the world smoothly along the curves of the coast line.

Here's what should happen in phase 1:

In phase 2, bits on the control map can be used to determine where water appears so it can be paintable. That means we can use this to make lakes, ponds, or puddles. The only thing I haven't figured out yet is how to set the height above the terrain while painting, and how to paint to make sure it covers the whole area, like if they just paint half of a pond, I suppose it will just float in the air until they paint the other half.

anandbarai09 commented 8 months ago

I would like to make a ocean system addon, so any idea how to implement??

Do you want to add an ocean to your game or do you want to make a PR for Terrain3D to build in an ocean?

If the first, you don't need to modify terrain3d or the shader at all. Just make a large plane node with the water shader that overlaps Terrain3D, then you can set our worldbackground to none. The water node will intersect with the terrain at every point on every curve. There will be some redundant meshes but it's easy to implement.

If you want to make a PR, then you should do what I said in my first comment.

Putting the oceanshader on the worldbackground flat mesh is going to be challenging to do. You'll run into problems blending with the rest of the world smoothly along the curves of the coast line.

Here's what should happen in phase 1:

* A second clipmap mesh is generated at a certain height above the terrain. This height is user settable

* The water clipmap gets the water shader

* There's a setting to enable/disable the water, and the height

In phase 2, bits on the control map can be used to determine where water appears so it can be paintable. That means we can use this to make lakes, ponds, or puddles. The only thing I haven't figured out yet is how to set the height above the terrain while painting, and how to paint to make sure it covers the whole area, like if they just paint half of a pond, I suppose it will just float in the air until they paint the other half.

Your Suggestion is good. But after doing some research I found unreal 4.27's water meshing system is simple and would be easy to integrate by creating a separate addon like Water3D which will interact will terrian3D like how proton scatter work. https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/Water/WaterRendering/

My Idea is: We will take a plane mesh with ocean material with some buoyancy logic. Then create a procedural water nodes like lakes,pond,river,stream,waterfall which will be child of the plane mesh. Which will align to the terrain. This is project_on_terrian3d works.

anandbarai09 commented 8 months ago

I will be create a new repo and create this as a separate addon. And give update of the addon in this issue.

TokisanGames commented 8 months ago

OK, sounds good. Will you support lake height? Say if they want a very deep lake in a high mountain, far above sea level. (eg Crater Lake in Oregon, USA)

How about rivers and water flow like water ways? So water can flow from that lake to the ocean.

anandbarai09 commented 8 months ago

Yes nice suggestions. Will try do it. Nice Idea of river water flow. Using flow map for river and ocean current map for ocean. Will make sense for open world games.

Tattomoosa commented 7 months ago

Godot4-OceanFFT has a very nice ocean shader implemented, and according to https://github.com/tessarakkt/godot4-oceanfft/issues/9 works with Terrain3D's existing GeoClipMap with a bit of setup.

I think a user desiring both a terrain and an ocean would be a fairly common occurrence and there are some common concerns which may justify a combined solution or at least some amount of collaboration between separate plugins (LODs, underwater terrain distance affecting water appearance, foam around terrain)

tessarakkt commented 7 months ago

I am on board with collaboration with this.

In phase 2, bits on the control map can be used to determine where water appears so it can be paintable. That means we can use this to make lakes, ponds, or puddles. The only thing I haven't figured out yet is how to set the height above the terrain while painting, and how to paint to make sure it covers the whole area, like if they just paint half of a pond, I suppose it will just float in the air until they paint the other half.

I don't think that painting a specific height above the terrain into the worls height map would be the way to go there. It would be a pain to calculate the correct heights for every point to generate an even surface. I would say painting on a base "sea level" relative the world, rather than a water surface relative the terrain, would be a better path.

I'm not sure how the terrain editor works in this plugin, but I am thinking something like the user clicks a point on the terrain as a point on the shoreline, and the editor calculates the path around the terrain at that height, and then fills in the water layer with the appropriate sea level (which would be the height the user clicked at). Planet Zoo would be a good example of what I am thinking of.

The water layer should be able to read the height of the terrain layer, as this will enable proper implementation of beaches and waves properly following the terrain. If a distance field can also be generated and baked into the map layers, that would be greatly helpful for this (see slide 25 in this link for a better description of the distance field and its purpose)

How about rivers and water flow like water ways? So water can flow from that lake to the ocean.

Large water bodies (oceans, seas, very large lakes, etc.), small water bodies (ponds, pools, etc.), and water ways are very different from each other and IMO warrant separate solutions. The line between a large and small body varies depending on the desired results.

The aptly named Waterways plugin implements water ways, and although I have not used it myself, I would think it more productive to work on improving that and integrating with it if needed rather than reinventing the wheel.

TokisanGames commented 7 months ago

We are using waterways in our game. Lw64 is on my team, and a contributor here. Duplicating the clipmap to use it as a mesh for the water is easy, as is applying a ready to go shader. A smooth workflow for the user still needs to be designed and implemented. I'm focused on other features at the moment.

@anandbarai09 How is your progress on your water system coming along?

anandbarai09 commented 7 months ago

We are using waterways in our game. Lw64 is on my team, and a contributor here. Duplicating the clipmap to use it as a mesh for the water is easy, as is applying a ready to go shader. A smooth workflow for the user still needs to be designed and implemented. I'm focused on other features at the moment.

@anandbarai09 How is your progress on your water system coming along?

Actually, it is currently in prototyping stage. I am designing how the system should work. So, the work done is Ocean3d node will be meshinstance with Lod (Can be quadtree or I am thinking of clipmap). As I am new to Godot Plugin Devlopment, I was learning the basics, so this took me long. As I finish my prototyping, I will create the public git repo. So, we can build it from scratch.

I actually had a question, Creating an Inheriting CSGPolygon3d node for WaterPolygon will be good, as in the docs it is written it is just for prototyping.

Godot4-OceanFFT has a very nice ocean shader implemented, and according to tessarakkt/godot4-oceanfft#9 works with Terrain3D's existing GeoClipMap with a bit of setup.

I think a user desiring both a terrain and an ocean would be a fairly common occurrence and there are some common concerns which may justify a combined solution or at least some amount of collaboration between separate plugins (LODs, underwater terrain distance affecting water appearance, foam around terrain)

Currently I am using the Realistic Water Shader as it has shoreline, foam, etc. and is looking good. But I have idea of integrating multiple shader (like boujie water shader, StayAtHomeDev's single plane water shader). So we can integrate OceanFFT water shader with it.

anandbarai09 commented 7 months ago

Godot4-OceanFFT has a very nice ocean shader implemented, and according to tessarakkt/godot4-oceanfft#9 works with Terrain3D's existing GeoClipMap with a bit of setup.

I think a user desiring both a terrain and an ocean would be a fairly common occurrence and there are some common concerns which may justify a combined solution or at least some amount of collaboration between separate plugins (LODs, underwater terrain distance affecting water appearance, foam around terrain)

I had gone through the repo. I will try to integrate it after prototyping in the final project.

TokisanGames commented 7 months ago

Ocean3d node will be meshinstance with Lod (Can be quadtree or I am thinking of clipmap).

Any water solution that we integrate in Terrain3D, I'm almost 100% that the underlying meshing system should be a clipmap so we can utilize existing same code. It doesn't make sense to me to introduce two meshing systems into the same plugin.

@anandbarai09 I know you are prototyping, but after that, I'd recommend you build something into Terrain3D so you can use our meshing system, rather than have a separate plugin. I can understand if you want to manage and market your own project, but having two plugins is the worst option for users. They already complain regularly that Terrain3D is not built into the core engine. I think if you make a separate plugin, we then need to build something else integrated into Terrain3D.

I don't think that painting a specific height above the terrain into the worls height map would be the way to go there. It would be a pain to calculate the correct heights for every point to generate an even surface.

The height can be absolute for an area, automatically calculated by the tool, but should be adjustable. Lakes exist above and below sea level.

I am thinking something like the user clicks a point on the terrain as a point on the shoreline, and the editor calculates the path around the terrain at that height, and then fills in the water layer with the appropriate sea level... the height the user clicked at

The water tool doesn't exist yet, so could be this or any other workflow. How the user uses the tool and how the data is represented are two different things though. We already have infrastructure that would allow water generation based on painted bits on a control map, which enable vertices on a water mesh. That's how holes, navigation, texturing already works and how foliage will as well. The tool could offer this fill option that automatically fills in the bits within a lake, and also generate any distance fields or flow maps.

The water layer should be able to read the height of the terrain layer

A clipmap terrain provides the height map to the shader, so a water shader can also read it.

Large water bodies (oceans, seas, very large lakes, etc.), small water bodies (ponds, pools, etc.), and water ways are very different from each other and IMO warrant separate solutions.

I'm pretty sure Witcher3 uses the same water shader for oceans, lakes, ponds, swamps, and puddles, just with different parameters. I see no issue doing this. A water control map that defines where water exists and its height can also define separate settings like color, turbulence, foam, etc for different areas.

Water that flows in rivers or water falls doesn't fit with standing water in my mind, though. Waterways can generate a flow map, so perhaps we can use that code. Getting Waterways to blend in with another water mesh means hiding the seam with rocks or particles. It's a bit clunky. A water system that could integrate both standing and flowing water would be amazing, but I'd consider that a phase 3+, nice to have feature.

So far we have @anandbarai09 who has started on a prototype, @tessarakkt with a good looking ocean shader, and on my team @lw64 and @rds1983 have expressed some interest. That's more than enough people, so my time is better spent on reviewing PRs, helping you integrate with or build on Terrain3D, and working on other things like foliage. You can all discuss here, or join us on our discord server in the #terrain-dev chat.

To reiterate what I'm looking for in a water system integrated in Terrain3D:

My recommendation of the development process is:

Phase 1 - Paintable water areas This is all pretty easy, just extending or copying existing code:

Phase 2 - Editor tool

Phase 3 - Flow This is a nice to have feature

anandbarai09 commented 7 months ago

Actually, Clipmap meshing system will only be used in Ocean3d node. And not in any part of water system. Other will be of node type Water Polygon which will be editable mesh shape. But according to your opinion (Which I think is good) so I will try to migrate the existing work to Terrian3d codebase.

Saul2022 commented 7 months ago

Godot4-OceanFFT has a very nice ocean shader implemented,

how is the performance cost tho? For igpu it may tank aome performance , though don’t know . Or maybe it can use a simpler method , like a scroling tiling texture( custom) , that uses a low resolution displacement map that moves the water. It what road to vostok seems to desire to use and it works performantly. https://twitter.com/roadtovostok/status/1742998083342844083

anandbarai09 commented 7 months ago

So I have started learning gdextension , c++ api for godot.

anandbarai09 commented 7 months ago

Godot4-OceanFFT has a very nice ocean shader implemented,

how is the performance cost tho? For igpu it may tank aome performance , though don’t know . Or maybe it can use a simpler method , like a scroling tiling texture( custom) , that uses a low resolution displacement map that moves the water. It what road to vostok seems to desire to use and it works performantly.

I actually tested demo on amd Radeon Vega 3 (igpu) which is very low end was about 10-15 fps. But I think we can optimize the performance..

TokisanGames commented 7 months ago

how is the performance cost tho?

The water mesh could have the option for a custom shader, like the terrain does. And probably any water shader could go on the mesh. So perhaps a simpler water shader could be an alternative. Especially one that works with the mobile and compatibility renderers.

lw64 commented 7 months ago

Godot4-OceanFFT has a very nice ocean shader implemented,

how is the performance cost tho? For igpu it may tank aome performance , though don’t know . Or maybe it can use a simpler method , like a scroling tiling texture( custom) , that uses a low resolution displacement map that moves the water. It what road to vostok seems to desire to use and it works performantly.

I actually tested demo on amd Radeon Vega 3 (igpu) which is very low end was about 10-15 fps. But I think we can optimize the performance..

Its a cpu bottleneck due to the quadtree

Saul2022 commented 7 months ago

I actually tested demo on amd Radeon Vega 3 (igpu) which is very low end was about 10-15 fps. But I think we can optimize the performance..

Ouch, that is my igpu 😂, well anyways custom shader could be used, and i already have that is way simpler.(though it just a plane mesh with a visual shader)

Edit: after tinkering with the addon demo, i got to 38 fps by resetting the values to their default value, in the quadtree like passing to the gpu and some options we could have like dissabling some effects and reduce the lods and region size. 17083360305143773577919657496287

Tattomoosa commented 7 months ago

You can render to a simple plane mesh with OceanFFT by applying the ocean material to it, ensuring it has enough subdivisions, and setting instance shader parameters to values compatible with the shader, for example:

patch_size = 512.0
min_lod_morph_distance = 0.0
max_lod_morph_distance = 1024.0

I've been doing a lot of work on the usability here, as well as getting previews working in-editor, so it may be easier to evaluate performance on my branch here but note it's still pretty experimental and rough around the edges: https://github.com/Tattomoosa/godot4-oceanfft/tree/ocean-tool-script - it has changes to faciltate setting up a quadtree more easily as well as rendering to a planemesh or multimesh with plane instances, as well as previewing the water simulation in the editor.

But I don't think there should be much concern about quadtree on your end anyway. OceanFFT currently intends to provide a built-in rendering solution but support a Terrain3D rendering solution if available. I'm going to be looking at implementing that as an optional integration fairly soon. There is a PR which provides it as a required integration by @lw64 that is probably worth checking out for testing purposes here: https://github.com/tessarakkt/godot4-oceanfft/pull/12

I haven't done extensive testing but from applying the ocean material to different meshes I get the sense the shader itself seems to perform fairly well, and the quadtree settings in the example scene are very expensive. The shader/simulation appears to work without issue on the Mobile renderer, but does not work on the Compatibility renderer. I think that's probably solvable, though.

I'm pretty sure Witcher3 uses the same water shader for oceans, lakes, ponds, swamps, and puddles, just with different parameters. I see no issue doing this. A water control map that defines where water exists and its height can also define separate settings like color, turbulence, foam, etc for different areas.

I think this makes a lot of sense, but I want to call out that, at least to my understanding, rivers probably warrant their own solution, and maybe a third solution to handle the transition between the two. This appears to be how Unreal does it: https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/Water/WaterRendering/

I also agree that it makes sense on your end for Terrain3D to ship a built-in water solution, but I think it also makes sense to support changing the shader completely, and for water in particular that tends to be a bit more complicated due to the simulation steps involved, at least as I understand it.

No opinion on whether your built-in solution should be OceanFFT or Realistic Water or something else but I hope it can be designed such that other water solutions can be used in place of the built-in one, although I do think it's acceptable if that requires some buy-in on the side of the water solution to integrate itself properly.

tessarakkt commented 7 months ago

The shader/simulation appears to work without issue on the Mobile renderer, but does not work on the Compatibility renderer. I think that's probably solvable, though.

The OceanFFT shader does not work in compatibility mode as the visual shader depends on the height maps being set, but they are implemented in compute shaders which are not available in Compatibility renderer. The Godot docs mention that compute shader support on mobile may be poor even when technically supported, so thats something to consider.

It is not feasible to reimplement the wave simulation on the CPU, as that would increase the CPU load to a point that few (if any) CPUs would be able to keep up with, especially if you want to actually have a game on top of it.

Other than that the visual shader should work fine (at least mostly) in Compatibility.

A wave simulation solution for systems that don't support compute shaders would probably involve prerendering the height maps on the dev system, and replaying them in game. Multiple height map sets can be prerendered at different settings for different weather, and then 2 sets interpolated for weather transitions. This is how Assassin's Creed 3 and 4 handled the ocean waves and weather transitions.

anandbarai09 commented 5 months ago

image I do i stitch the seam.????. Work of Ocean3DMaterial & Ocean3DStorage is done. Just the shader and this is remaining.

anandbarai09 commented 5 months ago

What is skirt mesh in geoclipmap ??

TokisanGames commented 5 months ago

Please see Mike Savage's blog. He wrote the base implementation.

https://mikejsavage.co.uk/geometry-clipmaps/

anandbarai09 commented 4 months ago

Skirt mesh and mesh stitching are done.

anandbarai09 commented 4 months ago

Can you suggest how to implement the sea level?? Because I tried it by setting sea level in vertex vector in geoclipmap

anandbarai09 commented 4 months ago

The remaining works are : sea level , water shader and water physics(buyouncy,etc).

TokisanGames commented 4 months ago

Can you suggest how to implement the sea level?? Because I tried it by setting sea level in vertex vector in geoclipmap

How are you storing and handling data now? It's hard to answer without context. Ground level is an aspect of the vertex shader, that positions the mesh vertices based upon the input height. I'd expect the vertex shader would position the water mesh vertices based upon a uniform value.

Do you have a fork and branch online to see how you're implementing things?

QuinnLeavitt commented 3 months ago

The remaining works are : sea level , water shader and water physics(buyouncy,etc).

I think for water meshes using GPU readbacks would be good for finding the height of a wave where the floating object is but support hasn't been added yet to the engine and the CPU would have to wait to get a response from the GPU before calculating the buoyancy which is already true for OceanFFT but it's slower currently due to needing to save the heightmap to a image/texture so the CPU can access it.

In the meantime you can use the heightmap image/texture of the water surface and use that just like the get_wave_height() function in the OceanFFT project. You can check the wave height against probes that are children of the floating object and apply the forces based on depth to those probes. For small simple objects just one probe should be good enough so that would be a good default and the users can create more as needed for other objects.

TokisanGames commented 1 month ago

Interesting discussion on discord regarding meshing for water, next pass, and vertex shader optimization. Start here and go a few pages to include discussion w/ Ansraer. https://discord.com/channels/691957978680786944/1065519581013229578/1264483731972952105