shader_type spatial; render_mode unshaded, cull_back, depth_draw_opaque; // Wave parameters: wave.xy is direction, wave.z is steepness, wave.w is wavelength. uniform vec4 color:source_color = vec4(0.13, 0.31, 0.53, 0.95); uniform vec4 wave = vec4(1.0, 0.0, 0.5, 10.0); uniform float wave_speed : hint_range(0.0, 5.0) = 1.0; uniform float gravity : hint_range(0.0, 20.0) = 9.8; uniform float wave_time; vec3 gerstnerWave(vec3 p, out vec3 tangent, out vec3 binormal) { float steepness = wave.z; float wavelength = wave.w; float k = 2.0 * PI / wavelength; float c = sqrt(gravity / k); vec2 d = normalize(wave.xy); float f = k * ( dot(d, p.xz) - c * wave_time * wave_speed ); float a = steepness / k; // Update tangent and binormal for lighting or other effects. tangent = vec3( -d.x * d.x * (steepness * sin(f)), d.x * (steepness * cos(f)), -d.x * d.y * (steepness * sin(f)) ); binormal = vec3( -d.x * d.y * (steepness * sin(f)), d.y * (steepness * cos(f)), -d.y * d.y * (steepness * sin(f)) ); return vec3( d.x * (a * cos(f)), a * sin(f), d.y * (a * cos(f)) ); } void vertex() { vec3 tangent; vec3 binormal; vec3 disp = gerstnerWave(VERTEX, tangent, binormal); VERTEX.xyz += disp; } void fragment() { ALBEDO = color.rgb; ALPHA = color.a; }