Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e110f5d
Checkpoint
xhocquet Jan 10, 2026
a0a3b61
Snapping WIP
xhocquet Jan 10, 2026
98aa8b7
WIP
xhocquet Jan 10, 2026
2cf084e
Waterfall decent spot
xhocquet Jan 10, 2026
13bc6fa
Improve updates for waterfall attrs
xhocquet Jan 10, 2026
2c3384f
Extract overshoot into export for waterfall
xhocquet Jan 10, 2026
b9aa972
More scene prep
xhocquet Jan 11, 2026
04d1e13
Lint
xhocquet Jan 11, 2026
7ec20a7
Expore material properties to editor
xhocquet Jan 11, 2026
c956bbd
Prepare waterfall UI for baking
xhocquet Jan 11, 2026
d104fe8
Lints and cleanup
xhocquet Jan 12, 2026
3dfc3ee
debug views on waterfall
xhocquet Jan 12, 2026
1cd6fac
Trim whitespace
xhocquet Jan 15, 2026
c8e89b5
Finally lint river manager
xhocquet Jan 15, 2026
31a8d6f
Standardize properties
xhocquet Jan 15, 2026
c587e62
Add defaults
xhocquet Jan 15, 2026
716012f
Add custom shader support
xhocquet Jan 15, 2026
cbea112
Lava waterfall support
xhocquet Jan 15, 2026
3569ca6
Add vertical support to lava shader
xhocquet Jan 16, 2026
8c4957b
Refactor start
xhocquet Jan 16, 2026
3c1386a
Refactor p2
xhocquet Jan 16, 2026
564ea4a
Refactor 4
xhocquet Jan 16, 2026
cd8e12d
refactor 5
xhocquet Jan 16, 2026
795f8eb
Refactor 6
xhocquet Jan 16, 2026
208908d
refactor 7
xhocquet Jan 16, 2026
b2bc851
Add gizmo line to waterfall
xhocquet Jan 16, 2026
b2fd95f
Side gizmo handle
xhocquet Jan 16, 2026
42b9f33
Add collision triangles for gizmos
xhocquet Jan 17, 2026
50f684b
Extract GUI operations
xhocquet Jan 17, 2026
3a9ffc7
Cleanup and remove lock
xhocquet Jan 17, 2026
c81f24a
Undo non-changes
xhocquet Jan 17, 2026
98a805c
Update README
xhocquet Jan 30, 2026
779277d
Add property description comments
xhocquet Jan 30, 2026
ea53d45
Update test scene with buoyant example
xhocquet Jan 30, 2026
ea8376c
Add waterfall note to README
xhocquet Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ addons/Todo_Manager/
.import/
export.cfg
export_presets.cfg
*.tmp

# Mono-specific ignores
.mono/
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

0.3.0
-----
- Waterfall component polished for release
- Nodes are now selectable from the viewport

0.2.1
-----
- New axis constraints for adding and moving river curve points (implemented by Winston)
Expand Down
81 changes: 55 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Waterways Add-on for Godot v0.1.0 Released - Feature Overview](https://raw.githubusercontent.com/Arnklit/media/main/WaterWaysAdd-on/screenshot01.jpg)](https://youtu.be/t54jUPFtRO8 "Waterways Add-on for Godot v0.1.0 Released - Feature Overview")

A tool to generate river meshes with flow and foam maps based on bezier curves. Try out the [demo project](https://github.com/Arnklit/WaterGenGodotDemo) for an example.
A tool to generate river meshes with flow and foam maps based on bezier curves.

[Discord Server](https://discord.gg/mjGvWwQwv2)

Expand All @@ -16,14 +16,37 @@ Purpose
-------
I've been very impressed with examples of using flowmaps to imitate water simulations in games for a while, but most of the implementations I've seen were using either manually painted flowmaps, or flowmaps generated in an external program. I wanted to see if it was possible to have good flowmap results purely generated within Godot. Both the generation of the flowmaps and the generation of the mesh for the river was of interest to me and I've learned a lot implementing my solution.

Godot Version Support
----------
Use the table below to determine which branch to use for your Godot version.

Note that newer updates are not made available in previous branches. The latest updates are pushed to the latest version branch.

| Godot Version | Supported | Branch |
| ------------- | --------- | --------- |
| 3.6 | Yes | [main](https://github.com/Arnklit/Waterways/tree/main) |
| 4.0 | Yes | [godot4_0](https://github.com/Arnklit/Waterways/tree/godot4_0) |
| 4.1 | Yes | [godot4_0](https://github.com/Arnklit/Waterways/tree/godot4_0) |
| 4.2 | Yes | [godot4_0](https://github.com/Arnklit/Waterways/tree/godot4_0) |
| 4.3 | Yes | [godot4_0](https://github.com/Arnklit/Waterways/tree/godot4_0) |
| 4.4 | Yes | [godot4_0](https://github.com/Arnklit/Waterways/tree/godot4_0) |
| 4.5 | Yes | [godot4_5_1](https://github.com/Arnklit/Waterways/tree/godot4_5_1) |

Demo Projects
-------------

For Godot 3.x, a sample project was maintained and can still be accessed [here](https://github.com/Arnklit/WaterGenGodotDemo).

Starting with Godot 4.0, a test scene is included in this repo to demonstrate the addon in action. Once you've loaded the addon, simply locate and open `test_scene.tscn`.

Usage
-----
Once the addon is active, you can simply add a River node to the scene.
![ZlC0D3OKaq](https://user-images.githubusercontent.com/4955051/105901753-b60fca80-6015-11eb-8ee5-4ac10b815ca0.gif)

**Shaping**

You can then use the Path controls to shape the river to your liking.
You can then use the Path controls to shape the river to your liking.
![FOa6ZrcTXA](https://user-images.githubusercontent.com/4955051/105954879-4af1e280-606d-11eb-9f53-bf60f701395e.gif)

The "Snap to Colliders" constraint can be used to easily place the path of the river along a terrain.
Expand Down Expand Up @@ -87,6 +110,12 @@ For effects such as this:

![UtzIm3ohmc](https://user-images.githubusercontent.com/4955051/104092678-75762a00-527d-11eb-9eff-18851b84a429.gif)

**Waterfall Nodes**

A *Waterfall* node is a newer node type that supports waterfall-like meshes. Check it out and give us feedback on it!

![Image](https://github.com/user-attachments/assets/474a800f-e341-4255-bdd4-ee7014ae88c6)


River Parameters
----------------
Expand Down Expand Up @@ -115,38 +144,38 @@ The river's parameters are split into 4 sections.
- *Roughness* - The roughness of the river surface, also affects the blurring that occurs in the refractions.
- *Edge Fade* - The distance the river fades out when it intesects other objects to give the shore line a softer look.
- *Flow* - Subcategory for flow options.
- *Speed* - How fast the river flows.
- *Base Strength* - Base multiplier of the flow vectors.
- *Steepness Strength* - Flow vectors multiplied by the steepness of the river.
- *Distance Strength* - Flow vectors multiplied by the distance field for faster flows further away from shore.
- *Pressure Strength* - Flow vectors multiplied by a pressure map, to imitate the flow increasing when there is less available space in the river.
- *Max Strength* - Clamps the maximum multiplier of the flow vectors.
- *Speed* - How fast the river flows.
- *Base Strength* - Base multiplier of the flow vectors.
- *Steepness Strength* - Flow vectors multiplied by the steepness of the river.
- *Distance Strength* - Flow vectors multiplied by the distance field for faster flows further away from shore.
- *Pressure Strength* - Flow vectors multiplied by a pressure map, to imitate the flow increasing when there is less available space in the river.
- *Max Strength* - Clamps the maximum multiplier of the flow vectors.

*Parameters specific to Water shader*

- *Albedo* - Subcategory for the albedo parameters.
- *Color* - The two colours of the water mixed based on the depth set in *Depth*.
- *Depth* - The water depth at which the far colour of the gradient is returned.
- *Depth Curve* - The interpolation curve used for the depth gradient.
- *Color* - The two colours of the water mixed based on the depth set in *Depth*.
- *Depth* - The water depth at which the far colour of the gradient is returned.
- *Depth Curve* - The interpolation curve used for the depth gradient.

- *Transparency* - Subcategory for the transparency parameters.
- *Clarity* - How far light can travel in the water before only returning the albedo colour.
- *Depth Curve* - The interpolation curve used for the clarity depth.
- *Refraction* - How much the background gets bent by the water shape.
- *Clarity* - How far light can travel in the water before only returning the albedo colour.
- *Depth Curve* - The interpolation curve used for the clarity depth.
- *Refraction* - How much the background gets bent by the water shape.

- *Foam* - Subcategory for the foam options.
- *Color* - The colour of the foam.
- *Ammount* - Controls the foam cutoff in the shader, you may have to use the foam baking setting to change the amount of foam further. See below.
- *Steepness* - Gives the option to add in foam where the river is steep.
- *Smoothness* - Controls how the foam layers are combined to give a sharper or softer look.
- *Color* - The colour of the foam.
- *Ammount* - Controls the foam cutoff in the shader, you may have to use the foam baking setting to change the amount of foam further. See below.
- *Steepness* - Gives the option to add in foam where the river is steep.
- *Smoothness* - Controls how the foam layers are combined to give a sharper or softer look.

*Parameters specific to the Lava shader*

- *Emission* - Subcategory for the emission options.
- *Color* - The two colours multiplied by the emission texture of the lava mixed based on the depth set in *Depth*.
- *Depth* - The lava depth at which the far colour of the gradient is returned.
- *Depth Curve* - The interpolation curve used for the depth gradient.
- *Texture* - The emission texture.
- *Color* - The two colours multiplied by the emission texture of the lava mixed based on the depth set in *Depth*.
- *Depth* - The lava depth at which the far colour of the gradient is returned.
- *Depth Curve* - The interpolation curve used for the depth gradient.
- *Texture* - The emission texture.

**Lod**

Expand Down Expand Up @@ -210,9 +239,9 @@ WaterSystem Parameters
- *System Group Name* - This group name is assigned at runtime, it is used by the *Buoyant* node to find the WaterSystem. If you only have one *WaterSystem*, you can just leave this be.
- *Minimum Water Level* - This is the value returned when an object queries the Water System heightmap, but hits outside the baked height data.
- *Auto Assign Texture & Coordinates On Generate* - Subcategory for auto assign setting, used to send the system map and coordinates to materials to be used in shaders
- *Wet Group Name* - This name will be used to find any *MeshInstances* that should have the maps assigned
- *Surface Index* - The surface index the material you want to send the maps to is set on the *MeshInstance*, -1 means disabled.
- *Material Override* - If the material is instead set as a Material Override, check this box for the maps to be assigned there.
- *Wet Group Name* - This name will be used to find any *MeshInstances* that should have the maps assigned
- *Surface Index* - The surface index the material you want to send the maps to is set on the *MeshInstance*, -1 means disabled.
- *Material Override* - If the material is instead set as a Material Override, check this box for the maps to be assigned there.

Buoyant Parameters
------------------
Expand Down
11 changes: 8 additions & 3 deletions addons/waterways/buoyant_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ extends Node3D

const WaterSystem = preload("res://addons/waterways/water_system_manager.gd")


## This is used to find the WaterSystem to get height and flow data from,
## this should match the value in your WaterSystem.
@export var water_system_group_name : String = "waterways_system"
## The amount of upwards force applied to the RigidBody when the Buoyant is under the water level.
@export var buoyancy_force := 5.0
## The amount of torque force added to the RigidBody to try and keep the object upright.
@export var up_correcting_force := 5.0
## The amount the flow vectors from the WaterSystem get's applied to the RigidBody.
@export var flow_force := 50.0
## This sets the RigidBody's damping parameter when under the water level.
@export var water_resistance := 5.0

var _rb : RigidBody3D
Expand Down Expand Up @@ -48,8 +53,8 @@ func _get_rotation_correction() -> Vector3:
var up_vector := global_transform.basis.y
var angle := up_vector.angle_to(Vector3.UP)
if angle < 0.1:
# Don't reaturn a rotation as object is almost upright, since the cross
# product at an angle that small might cause precission errors.
# Don't return a rotation as object is almost upright, since the cross
# product at an angle that small might cause precision errors.
return Vector3.ZERO
var cross := up_vector.cross(Vector3.UP).normalized()
rotation_transform = rotation_transform.rotated(cross, angle)
Expand Down
56 changes: 56 additions & 0 deletions addons/waterways/consts.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const MATERIAL_CATEGORIES = {
albedo_ = "Albedo",
emission_ = "Emission",
transparency_ = "Transparency",
flow_ = "Flow",
foam_ = "Foam",
custom_ = "Custom",
}

const FILTER_RENDERER_PATH = "res://addons/waterways/filter_renderer.tscn"
const FLOW_OFFSET_NOISE_TEXTURE_PATH = "res://addons/waterways/textures/flow_offset_noise.png"
const FOAM_NOISE_PATH = "res://addons/waterways/textures/foam_noise.png"

enum SHADER_TYPES { WATER, LAVA, CUSTOM }

const BUILTIN_SHADERS = [
{
name = "Water",
shader_path = "res://addons/waterways/shaders/river.gdshader",
texture_paths = [
{
name = "normal_bump_texture",
path = "res://addons/waterways/textures/water1_normal_bump.png",
},
],
},
{
name = "Lava",
shader_path = "res://addons/waterways/shaders/lava.gdshader",
texture_paths = [
{
name = "normal_bump_texture",
path = "res://addons/waterways/textures/lava_normal_bump.png",
},
{
name = "emission_texture",
path = "res://addons/waterways/textures/lava_emission.png",
},
],
},
]

const DEBUG_SHADER = {
name = "Debug",
shader_path = "res://addons/waterways/shaders/river_debug.gdshader",
texture_paths = [
{
name = "debug_pattern",
path = "res://addons/waterways/textures/debug_pattern.png",
},
{
name = "debug_arrow",
path = "res://addons/waterways/textures/debug_arrow.svg",
},
],
}
1 change: 1 addition & 0 deletions addons/waterways/consts.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://b7qn61h85oeh6
9 changes: 3 additions & 6 deletions addons/waterways/editor_property.gd
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
# Copyright © 2023 Kasper Arnklit Frandsen - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends EditorProperty

const GradientInspector = preload("./gui/gradient_inspector.gd")

var _ui : GradientInspector
var _ui: GradientInspector
var _updating := false


func _init() -> void:
_ui = preload("res://addons/waterways/gui/gradient_inspector.tscn").instantiate() as Control
add_child(_ui)
add_child(_ui)
set_bottom_editor(_ui)
(_ui.get_node("Color1") as ColorPickerButton).color_changed.connect(gradient_changed)
(_ui.get_node("Color2") as ColorPickerButton).color_changed.connect(gradient_changed)


func gradient_changed(_val) -> void:
print("gradient changed")
if _updating:
return
var value = _ui.get_value()
emit_changed(get_edited_property(), value)


func _update_property() -> void:
print("update_property in editor_property.gd")
var new_value = get_edited_object()[get_edited_property()]
_updating = true
_ui.set_value(new_value)
Expand Down
2 changes: 1 addition & 1 deletion addons/waterways/filter_renderer.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://dvyvnh61c27fq"]

[ext_resource type="Script" path="res://addons/waterways/filter_renderer.gd" id="1"]
[ext_resource type="Script" uid="uid://x3cy4mocin5r" path="res://addons/waterways/filter_renderer.gd" id="1"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_n87ho"]

Expand Down
4 changes: 2 additions & 2 deletions addons/waterways/gui/gradient_inspector.tscn
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://c34hw5u3n1nnt"]

[ext_resource type="Script" path="res://addons/waterways/gui/gradient_inspector.gd" id="1"]
[ext_resource type="Shader" path="res://addons/waterways/shaders/gui/gradient.gdshader" id="2"]
[ext_resource type="Script" uid="uid://bbptp3mw8uyta" path="res://addons/waterways/gui/gradient_inspector.gd" id="1"]
[ext_resource type="Shader" uid="uid://birl6x2dlqf58" path="res://addons/waterways/shaders/gui/gradient.gdshader" id="2"]

[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v5c7w"]
bg_color = Color(1, 1, 1, 1)
Expand Down
92 changes: 92 additions & 0 deletions addons/waterways/gui/gui_manager.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
@tool
extends RefCounted

signal generate_flowmap_pressed
signal generate_mesh_pressed
signal debug_view_changed(index: int)
signal generate_system_maps_pressed

var _river_controls = preload("./river_controls.tscn").instantiate()
var _waterfall_controls = preload("./waterfall_controls.tscn").instantiate()
var _water_system_controls = preload("./water_system_controls.tscn").instantiate()
var _plugin: EditorPlugin


func _init(plugin: EditorPlugin) -> void:
_plugin = plugin


func get_river_controls():
return _river_controls


func get_waterfall_controls():
return _waterfall_controls


func get_water_system_controls():
return _water_system_controls


func hide_all_control_panels() -> void:
hide_river_control_panel()
hide_water_system_control_panel()
hide_waterfall_control_panel()


func show_river_control_panel() -> void:
if not _river_controls.get_parent():
_plugin.add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _river_controls)
_river_controls.menu.connect("generate_flowmap", _on_generate_flowmap_pressed)
_river_controls.menu.connect("generate_mesh", _on_generate_mesh_pressed)
_river_controls.menu.connect("debug_view_changed", _on_debug_view_changed)


func hide_river_control_panel() -> void:
if _river_controls.get_parent():
_plugin.remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _river_controls)
_river_controls.menu.disconnect("generate_flowmap", _on_generate_flowmap_pressed)
_river_controls.menu.disconnect("generate_mesh", _on_generate_mesh_pressed)
_river_controls.menu.disconnect("debug_view_changed", _on_debug_view_changed)


func show_water_system_control_panel() -> void:
if not _water_system_controls.get_parent():
_plugin.add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _water_system_controls)
_water_system_controls.menu.connect("generate_system_maps", _on_generate_system_maps_pressed)


func hide_water_system_control_panel() -> void:
if _water_system_controls.get_parent():
_plugin.remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _water_system_controls)
_water_system_controls.menu.disconnect("generate_system_maps", _on_generate_system_maps_pressed)


func show_waterfall_control_panel() -> void:
if not _waterfall_controls.get_parent():
_plugin.add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _waterfall_controls)
_waterfall_controls.menu.connect("generate_flowmap", _on_generate_flowmap_pressed)
_waterfall_controls.menu.connect("debug_view_changed", _on_debug_view_changed)


func hide_waterfall_control_panel() -> void:
if _waterfall_controls.get_parent():
_plugin.remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _waterfall_controls)
_waterfall_controls.menu.disconnect("generate_flowmap", _on_generate_flowmap_pressed)
_waterfall_controls.menu.disconnect("debug_view_changed", _on_debug_view_changed)


func _on_generate_flowmap_pressed() -> void:
emit_signal("generate_flowmap_pressed")


func _on_generate_mesh_pressed() -> void:
emit_signal("generate_mesh_pressed")


func _on_debug_view_changed(index: int) -> void:
emit_signal("debug_view_changed", index)


func _on_generate_system_maps_pressed() -> void:
emit_signal("generate_system_maps_pressed")
1 change: 1 addition & 0 deletions addons/waterways/gui/gui_manager.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://c5r27wsd24464
2 changes: 1 addition & 1 deletion addons/waterways/gui/progress_window.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://bkr2n0e2drrc4"]

[ext_resource type="Script" path="res://addons/waterways/gui/progress_window.gd" id="1_xgojc"]
[ext_resource type="Script" uid="uid://c2fbj6j2ds71r" path="res://addons/waterways/gui/progress_window.gd" id="1_xgojc"]

[node name="Popup" type="PopupPanel"]
title = "Test"
Expand Down
Loading