1 #define FMA(a, b, c) ((a) * (b) + (c)) // fused multiply-add
5 const float kTile = 1.;
7 const float kPi = 3.1415926535;
8 const float kEpsilon = 1. / 32.;
12 uniform mat4 uModelView;
13 uniform mat4 uProjection;
14 uniform mat3 uNormalMatrix;
18 uniform vec2 uScrollScale;
19 uniform float uWaveRate;
20 uniform float uWaveAmplitude;
21 uniform float uParallaxAmount;
23 attribute vec2 aPosition;
24 attribute vec2 aTexCoord;
27 varying vec3 vViewPos;
29 varying float vHeight;
31 float CubicHermite(float B, float C, float t)
33 float dCB = (C - B) * .5;
36 vec3 p = vec3(D + .5 * (((B - C) * 3.) - A), A - 2.5 * B + 2. * C - D,
38 return FMA(FMA(FMA(p.x, t, p.y), t, p.z), t, B);
43 return fract(sin(n) * 43751.5453123);
46 float HeightAtTile(vec2 pos)
48 float rate = Hash(Hash(pos.x) * Hash(pos.y));
50 return (sin(uTime * rate * uWaveRate) * .5 + .5) * uWaveAmplitude;
53 float CalculateHeight(vec2 position)
55 vec2 tile = floor(position);
56 position = fract(position);
60 HeightAtTile(tile + vec2( kTile * -0.5, kTile * -0.5)),
61 HeightAtTile(tile + vec2( kTile * +0.5, kTile * -0.5)),
64 HeightAtTile(tile + vec2( kTile * -0.5, kTile * +0.5)),
65 HeightAtTile(tile + vec2( kTile * +0.5, kTile * +0.5)),
69 return CubicHermite(cp.x, cp.y, position.y);
72 vec3 CalculateNormal(vec2 position)
75 CalculateHeight(vec2(position.x - kEpsilon, position.y)) -
76 CalculateHeight(vec2(position.x + kEpsilon, position.y)),
78 CalculateHeight(vec2(position.x, position.y - kEpsilon)) -
79 CalculateHeight(vec2(position.x, position.y + kEpsilon))
88 vec2 scrollPosition = aPosition * uScrollScale + vec2(0., uTime * -kPi);
89 vNormal = uNormalMatrix * CalculateNormal(scrollPosition);
91 float h = CalculateHeight(scrollPosition);
92 vHeight = h * uParallaxAmount;
93 vec3 position = vec3(aPosition.x, h, aPosition.y);
95 vec4 viewPosition = uModelView * vec4(position * uSize, 1.);
96 vViewPos = -viewPosition.xyz;
98 gl_Position = uProjection * viewPosition;