waves.vert
2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#define FMA(a, b, c) ((a) * (b) + (c)) // fused multiply-add
precision highp float;
const float kTile = 1.;
const float kPi = 3.1415926535;
const float kEpsilon = 1. / 32.;
// DALI uniforms
uniform vec3 uSize;
uniform mat4 uModelView;
uniform mat4 uProjection;
uniform mat3 uNormalMatrix;
// our uniforms
uniform float uTime;
uniform vec2 uScrollScale;
uniform float uWaveRate;
uniform float uWaveAmplitude;
uniform float uParallaxAmount;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
varying vec2 vUv;
varying vec3 vViewPos;
varying vec3 vNormal;
varying float vHeight;
float CubicHermite(float B, float C, float t)
{
float dCB = (C - B) * .5;
float A = B - dCB;
float D = B + dCB;
vec3 p = vec3(D + .5 * (((B - C) * 3.) - A), A - 2.5 * B + 2. * C - D,
.5 * (C - A));
return FMA(FMA(FMA(p.x, t, p.y), t, p.z), t, B);
}
float Hash(float n)
{
return fract(sin(n) * 43751.5453123);
}
float HeightAtTile(vec2 pos)
{
float rate = Hash(Hash(pos.x) * Hash(pos.y));
return (sin(uTime * rate * uWaveRate) * .5 + .5) * uWaveAmplitude;
}
float CalculateHeight(vec2 position)
{
vec2 tile = floor(position);
position = fract(position);
vec2 cp = vec2(
CubicHermite(
HeightAtTile(tile + vec2( kTile * -0.5, kTile * -0.5)),
HeightAtTile(tile + vec2( kTile * +0.5, kTile * -0.5)),
position.x),
CubicHermite(
HeightAtTile(tile + vec2( kTile * -0.5, kTile * +0.5)),
HeightAtTile(tile + vec2( kTile * +0.5, kTile * +0.5)),
position.x)
);
return CubicHermite(cp.x, cp.y, position.y);
}
vec3 CalculateNormal(vec2 position)
{
vec3 normal = vec3(
CalculateHeight(vec2(position.x - kEpsilon, position.y)) -
CalculateHeight(vec2(position.x + kEpsilon, position.y)),
.25,
CalculateHeight(vec2(position.x, position.y - kEpsilon)) -
CalculateHeight(vec2(position.x, position.y + kEpsilon))
);
return normal;
}
void main()
{
vUv = aTexCoord;
vec2 scrollPosition = aPosition * uScrollScale + vec2(0., uTime * -kPi);
vNormal = uNormalMatrix * CalculateNormal(scrollPosition);
float h = CalculateHeight(scrollPosition);
vHeight = h * uParallaxAmount;
vec3 position = vec3(aPosition.x, h, aPosition.y);
vec4 viewPosition = uModelView * vec4(position * uSize, 1.);
vViewPos = -viewPosition.xyz;
gl_Position = uProjection * viewPosition;
}