commit 39b80df0caee094223bbd6a247e20b502046df0c
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Sun Oct 9 23:42:52 2016 +0100

    Shades of the WAVE effect (almost!) working.

diff --git a/build.gradle b/build.gradle
index f0a2322..fb81889 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
 
 android {
     compileSdkVersion 23
-    buildToolsVersion "23.0.3"
+    buildToolsVersion "24.0.3"
 
     defaultConfig {
         minSdkVersion 18
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index a093478..00ec5b2 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -350,20 +350,46 @@ void swirl(in int effect, inout vec4 v)
 void wave(in int effect, inout vec4 v, inout vec4 n)
   {
   vec2 center     = vUniforms[effect+1].zw;
-  float sinA      = vUniforms[effect  ].y;
-  float cosA      = vUniforms[effect+1].x;
-  float sinB      = vUniforms[effect  ].w;
-  float cosB      = vUniforms[effect+1].y;
   float amplitude = vUniforms[effect  ].x;
   float length    = vUniforms[effect  ].z;
 
   vec2 ps = center-v.xy;
   float deg = amplitude*degree_region(vUniforms[effect+2],ps);
 
-  if( deg != 0.0 )
+  if( deg != 0.0 && length != 0.0 )
     {
-    float angle = length==0.0 ? 0.0 : 1.578*(ps.x*cosB+ps.y*sinB) / length;
-    v.xyz += sin(angle)*deg*vec3(sinB*cosA,cosB*cosA,sinA);
+    float sinA   = vUniforms[effect  ].y;
+    float cosA   = vUniforms[effect+1].x;
+    float sinB   = vUniforms[effect  ].w;
+    float cosB   = vUniforms[effect+1].y;
+
+    float angle = 1.578*(ps.x*cosB+ps.y*sinB) / length;
+    vec3 dir    = vec3(sinB*cosA,cosB*cosA,sinA);
+
+    v.xyz += sin(angle)*deg*dir;
+
+    float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z);
+    float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z);
+
+    float sinX = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX);
+    float cosX = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX);
+    float sinY = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY);
+    float cosY = ( sqrtY==0.0 ? 1.0 : dir.y / sqrtY);
+
+    float tmp = 1.578*cos(angle)*deg/length;
+
+    float fx = cosB*tmp;
+    float fy = sinB*tmp;
+
+    vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,sinY*sinX*fx);
+    vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,sinX*sinY*fy);
+
+    vec3 normal = cross(sx,sy);
+
+    if( n.z != 0.0 )
+      {
+      n.xyz = n.z*normal;
+      }
     }
   }
 
