water shader by HexagonNico
Shader Description: Dynamic Distortion and Wave Effect for Canvas Items
This Godot 4 canvas item shader applies a dynamic distortion effect to a texture using noise while also introducing a wave motion to the vertices. The shader blends the object’s texture with the screen texture, creating a visually appealing ripple effect.
Functionality Overview
-
Vertex Manipulation (Wave Motion)
- The
vertex()
function applies a simple sinusoidal wave to the Y-axis of the object’s vertices. - This creates a subtle vertical oscillation effect, making the object appear to “wiggle” over time.
- The
-
Fragment Shader (Texture Distortion & Blending)
-
Dynamic Noise-Based Distortion
- A noise texture (
nois_texture
) is used to create a distortion effect. - The noise is sampled with animated UV coordinates (
uv + speed * TIME
). - The noise values are adjusted to range from -1 to 1 for proper distortion.
- A noise texture (
-
Texture Warping
- The main texture (
TEXTURE
) is distorted using noise multiplied bywave_strength
. - The screen texture (
screen_texture
) is also distorted, but using a separatedistortion
factor. - The final output is the multiplication of both textures, resulting in an interactive blending effect.
- The main texture (
-
Key Uniforms and Their Effects
Uniform | Description |
---|---|
screen_texture |
Captures the screen’s texture to be blended with the object. |
nois_texture |
Provides a noise pattern to distort the texture dynamically. |
distortion |
Controls how much the screen texture is warped by noise. |
speed |
Determines the movement speed of the noise pattern. |
wave_strength |
Adjusts the strength of the texture warping effect. |
Visual Effect Summary
- Wave Motion: The object moves slightly up and down in a sinusoidal pattern.
- Texture Distortion: The texture is dynamically warped by noise, creating a wavy, liquid-like effect.
- Screen Texture Interaction: The object blends with the screen texture, producing a dynamic overlay effect.
Shader code
shader_type canvas_item;
uniform sampler2D screen_texture: hint_screen_texture;
uniform sampler2D nois_texture: filter_nearest, repeat_enable;
uniform float distortion = 0.01;
uniform vec2 speed = vec2(0.5, 0.2);
uniform float wave_strength = 0.02;
void vertex(){
VERTEX.y += sin(TIME);
}
void fragment(){
vec2 uv = UV + speed * TIME;
vec2 noise = 2.0 * texture(nois_texture, uv).rg - vec2(1.0);
COLOR = texture(TEXTURE, UV + noise * wave_strength);
COLOR*= texture(screen_texture, SCREEN_UV + noise * distortion);
}