home Gerstner Waves with Dynamic Lighting Gerstner waves is a simple yet effective way to simuate the motion of water waves. This implementation
uses a flat plane geometry with the gerstner waves produced directly in the vertex shader.
vec3 gertsnerWave ( vec4 wave , vec3 point , inout vec3 tangent , inout vec3 binormal ){
vec2 d = normalize ( wave . xy );
float s = wave . z ; // steepness
float lambda = wave . w ; // wavelength
float k = 2.0 * PI / lambda ;
float c = sqrt ( 1.0 / k ); // Should be 9.81 / k but reduced for slower speed.
float f = k * ( dot ( d , point . xz ) - ( c * u_Time ));
Since the motion of the wave is explicitly defined, the normals can be calculated to allow for correct lighting and shadows.
vec3 gertsnerWave ( vec4 wave , vec3 point , inout vec3 tangent , inout vec3 binormal ){
// Compute normals, then pass to the fragment shader
tangent += vec3 (- d . x * d . x * ( s * sin ( f )),
- d . x * d . y * ( s * sin ( f )));
binormal += vec3 (- d . x * d . y * ( s * sin ( f )),
- d . y * d . y * ( s * sin ( f )));
return vec3 ( d . x * ( s / k * cos ( f )),
v_Normal = normalize ( cross ( binormal , tangent ));
vec3 lightReflection ( vec3 lightColor , vec3 surfaceToLight ){
vec3 normal = normalize ( v_Normal );
// Set ambient, calculate dot product for light levels on normal faces
vec3 ambient = lightColor ;
vec3 diffuse = lightColor * dot ( surfaceToLight , normal );
return ( ambient + diffuse );