This is what I implemented so far, I need to add splashes and boat foam trail, any basic ideas?
Shader code:
shader_type spatial;
// portions stolen from Krzysztof Jankowski's the islands of shaders repo.
// (It is brilliant!)
// Also some lines are from various places on the Internet.
uniform vec2 timescale = vec2(2.0, 3.0);
uniform float refraction = 0.05;
uniform float large_waveheight = 0.15;
uniform float small_waveheight = 0.05;
// This one I generated this way. I created 2D Vewport with canvas in it
// Made 2D shader and used Krzysztof Jankowski's random function to fill the screen
// and use the viewport texture for this uniform.
uniform sampler2D random_noise: hint_black;
varying vec3 coords;
// 2d noise function
// For some reason random function produced
// too many artifacts, so I had to replace it by texture.
float noise(vec2 p)
{
vec4 tx = textureLod(random_noise, p, 0.5);
return tx.x;
}
// Fractional Brownian motion
float fbm( vec2 p )
{
mat2 m2 = mat2(vec2(1.6, -1.2), vec2(1.2, 1.6));
float f = 0.5000 * noise(p); p = m2*p;
f += 0.2500 * noise( p ); p = m2*p;
f += 0.1666 * noise( p ); p = m2*p;
f += 0.0834 * noise( p );
return f;
}
float water(vec2 p, float time)
{
vec2 pos = p;
mat2 m2 = mat2(vec2(1.6, -1.2), vec2(1.2, 1.6));
float h = 0.0;
vec2 shift1 = 0.001 * vec2(time * 160.0 * 2.0, time * 120.0 * 2.0) * 1.0;
vec2 shift2 = 0.001 * vec2(time * 190.0 * 2.0, -time * 130.0 * 2.0) * 1.0;
float wave = 0.0;
wave += sin(pos.x*0.021 * 10.0 + shift2.x)*4.5;
wave += sin(pos.x*0.0172 * 10.0 + pos.y * 0.010 * 10.0+ shift2.x*1.121)*4.0;
wave -= sin(pos.x*0.00104 * 10.0 + pos.y*0.005 * 10.0 + shift2.x*0.121)*4.0;
wave += (1.0 - abs(cos(4.5 * (pos.x*0.0172 * 10.0 + pos.y * 0.010 * 10.0+ shift2.x*1.121)))) * 0.7;
wave += (1.0 - abs(cos(5.5 * (pos.x*0.0172 * 10.0 + pos.y * 0.010 * 10.0+ shift2.x*1.121)))) * 0.5;
wave += (1.0 - abs(cos(8.5 * (pos.x*0.0172 * 10.0 + pos.y * 0.010 * 10.0+ shift2.x*1.121)))) * 0.2;
// wave += sin(pos.x*0.02221 * 10.0 +pos.y*0.01233 * 10.0 +shift2.x*3.437)*5.0;
// wave += sin(pos.x*0.03112 * 10.0 +pos.y*0.01122 * 10.0 +shift2.x*4.269)*2.5;
wave *= large_waveheight;
wave -= fbm(pos*0.004 - shift2 * 0.5) * small_waveheight * 24.0;
float amp = 16.0 * small_waveheight;
shift1 *= .3;
for (int i=0; i<7; i++)
{
wave -= abs(sin((noise(pos*0.01+shift1)-.5)*3.14))*amp;
amp *= .51;
shift1 *= 1.841;
pos = m2 * 0.9331 * pos;
}
h += wave;
return h;
}
void vertex()
{
vec4 vtx = vec4(VERTEX, 1.0);
vec4 worldv = WORLD_MATRIX * vtx;
VERTEX.y = water(vec2(worldv.x, worldv.z), TIME);
float hdiff = water(worldv.xz + vec2(0.0, 0.2), 0.0) - water(worldv.xz + vec2(0.0, -0.2), 0.0);
float hdiff2 = water(worldv.xz + vec2(0.2, 0.0), 0.0) - water(worldv.xz + vec2(-0.2, 0.0), 0.0);
TANGENT = normalize(vec3(0.0, hdiff, 0.4));
BINORMAL = normalize(vec3(0.4, hdiff2, 0.0));
NORMAL = cross(TANGENT, BINORMAL);
coords = VERTEX.xyz;
}
void fragment()
{
ALBEDO = vec3(0, 0, 1);
ROUGHNESS = 0.2;
METALLIC = 0.5;
vec2 uv_offsets = vec2(0.0, 0.0);
uv_offsets.x += 0.12 * sin(TIME * 0.02 + UV.x);
uv_offsets.x += 0.05 * sin(TIME * 3.0 + UV.x);
uv_offsets.y += 0.12 * cos(TIME * 0.02 + UV.y);
uv_offsets.y += 0.05 * cos(TIME * 3.0 + UV.y);
vec3 ref_normal = normalize(mix(NORMAL, TANGENT * uv_offsets.x + BINORMAL * uv_offsets.y + NORMAL * NORMALMAP.z, NORMALMAP_DEPTH));
vec2 ref_ofs = SCREEN_UV + ref_normal.xy * refraction;
ALPHA = 0.4;
EMISSION += textureLod(SCREEN_TEXTURE, ref_ofs, ROUGHNESS * 8.0).rgb * (1.0 - ALPHA);
ALBEDO *= ALPHA;
ALPHA = 1.0;
}