Arnklit / Waterways

A tool to generate river meshes with flow and foam maps based on bezier curves.
https://github.com/Arnklit/WaterGenGodotDemo
MIT License
1.03k stars 68 forks source link
flowmap godot river

Waterways Add-on for Godot Engine

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 for an example.

Discord Server

Patreon

Installation

Copy the folder addons/waterways into your project and activate the add-on from the Project -> Project Settings... -> Plugins menu.

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.

Usage

Once the addon is active, you can simply add a River node to the scene. ZlC0D3OKaq

Shaping

You can then use the Path controls to shape the river to your liking. FOa6ZrcTXA

The "Snap to Colliders" constraint can be used to easily place the path of the river along a terrain. Uo0Yts7nj6

The Axis and Plane constraints can be used for better control in moving and adding points. The implementation is similar to Blender's. You can also use the shortcuts X, Y and Z to lock movement to a given axis and shortcuts Shift + X, Y and Z to lock to planes YZ, XZ and XY. The Local mode option, switches the axis to be local to the point rather than the world and can be toggled with shortcut T. qK2oHGFXFO

Texture Baking

Once you are happy with the shape of your river, you can use the River -> Generate Flow & Foam Map option to bake out the textures that activate flow map and foam. The settings for the baking are located in the river's inspector, see section below. GU7fDHXmmJ

Generating a Mesh Copy

In case you want to access the river mesh directly to use it for other purposes such as generating a collision shape. You can use the River -> Generate MeshInstance Sibling option. b5qdG0oYbV

Using a WaterSystem Node

To generate a global height and flowmap of a river. You can add a WaterSystem node and generate a texture based on any River child nodes with the WaterSystem -> Generate System Maps option. bnhOeLjP8H

Using a Buoyant Node

Adding a Buoyant node as a child to a RigidBody will allow the object to float on the river if a WaterSystem with valid maps is available. image

Using flow and height maps in shaders

You can automatically assign the global textures from the WaterSystem node to MeshInstances to use them in shaders. See the WaterSystem parameters for details. Once the textures and coordinates are assigned you can use them in a shader like this:

shader_type spatial;

uniform sampler2D water_systemmap;
uniform mat4 water_systemmap_coords;
varying vec3 world_vertex;

float water_altitude(vec3 pos) {
    vec3 pos_in_aabb = pos - water_systemmap_coords[0].xyz;
    vec2 pos_2d = vec2(pos_in_aabb.x, pos_in_aabb.z);
    float longest_side = water_systemmap_coords[1].x > water_systemmap_coords[1].z ? water_systemmap_coords[1].x : water_systemmap_coords[1].z;
    pos_2d = pos_2d / longest_side;
    float value = texture(water_systemmap, pos_2d).b;
    float height = value * water_systemmap_coords[1].y + water_systemmap_coords[0].y;
    return pos.y - height;
}

void vertex() {
    world_vertex = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz;
}

void fragment() {
    float altitude = clamp(water_altitude(world_vertex), 0.0, 1.0);
    ALBEDO = vec3(altitude);
}

For effects such as this:

UtzIm3ohmc

River Parameters

The river's parameters are split into 4 sections.

Shape

Material

The Material section has two hardcoded parameters

The remaining parameters in the Material section are parsed from the currect shader

Parameters shared by Water and Lava shader

Parameters specific to Water shader

Parameters specific to the Lava shader

Lod

Baking

Writing Custom Shaders

When writing custom shaders for the tool there are a few things to keep in mind.

The tool uses certain uniforms that should not be customized as that will break the tool. These uniforms are prefixed with "i_" and are:

Uniform name Description
i_lod0_distance used by the LOD system
i_texture_foam_noise a noise texture used to display foam on steep angles
i_flowmap the generated flowmap(RG) and foam map(B)
i_distmap the generated distance field(R) and pressure map(B)
i_valid_flowmap a bool that is set if the generated maps are valid
i_uv2_sides an int value that tells the shader how to read the UV2 layout

Uniforms that do not start with "i_" will be parsed by the river's material inspector so they can easily be used in the tool. If the uniforms start with any of the below prefixes they will automatically be sorted into subcategories in the material section.

Prefix name Subcatergory name
albedo_ Albedo
emission_ Emission
transparency_ Transparency
flow_ Flow
foam_ Foam
custom_ Custom

Additionally the river inspector will handle these uniform types specially:

float uniforms containing "curve" in their name will be displayed as an easing curve in the inspector.

uniform float albedo_depth_curve = 0.25;

image

mat4 uniforms containing "color" in their name will be displayed as a gradient field with two colour selectors. Here is the code setting up the water shader's albedo gradient with the two colors (0.0, 0.8, 1.0) and (0.15, 0.2, 0.5).

uniform mat4 albedo_color = mat4(vec4(0.0, 0.15, 0.0, 0.0), vec4(0.8, 0.2, 0.0, 0.0), vec4(1.0, 0.5, 0.0, 0.0), vec4(0.0));

image

WaterSystem Parameters

Buoyant Parameters

Current Limitations

Acknowledgements

Several people in the Godot community have helped me out with this.

Beyond the Godot community, I should also mention these resources.

Contributing

If you want to contribute to the project or just work on your own version, clone the repository and add Zylann's terrain addon into the project as I don't include it in this repository, but use it in the test scene.