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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
shader_type spatial;
render_mode cull_disabled, depth_draw_always;
uniform vec3 wave1 = vec3(0.5,0.5,0.5);
uniform vec2 wave1_dir = vec2(1.0,0.0);
uniform float wave1_t = 0.0;
uniform vec3 wave2 = vec3(0.5,0.5,0.5);
uniform vec2 wave2_dir = vec2(1.0,0.0);
uniform float wave2_t = 0.0;
uniform vec3 wave3 = vec3(0.5,0.5,0.5);
uniform vec2 wave3_dir = vec2(1.0,0.0);
uniform float wave3_t = 0.0;
uniform vec4 water_color : hint_color;
uniform vec4 foam_color: hint_color;
uniform sampler2D foam_map;
uniform float foam_amount_edge = 2.0;
uniform float foam_amount_crest = 4.0;
uniform float murkiness = 4.0;
uniform float refraction_amount = 0.01;
uniform sampler2D noise;
varying vec3 global_vertex;
varying vec3 displacement;
vec3 gerstner_wave(vec3 wave, vec2 wave_dir, float t, vec3 pos, inout vec3 tangent, inout vec3 binormal)
{
float steepness = wave.x;
float k = wave.y;
float a = wave.z;
vec2 d = normalize(wave_dir);
float f = k * (dot(d,pos.xz) - t);
float tmp1 = steepness * sin(f);
float tmp2 = steepness * cos(f);
tangent += vec3(
-d.x * d.x * tmp1,
d.x * tmp2,
-d.x * d.y * tmp1
);
binormal += vec3(
-d.x * d.y * tmp1,
d.y * tmp2,
-d.y * d.y * tmp1
);
float tmp3 = a * cos(f);
vec3 new_pos = vec3(
d.x * tmp3,
a * sin(f),
d.y * tmp3
);
return new_pos;
}
void vertex()
{
global_vertex = (WORLD_MATRIX * vec4(VERTEX,1.0)).xyz;
TANGENT = vec3(1.0,0.0,0.0);
BINORMAL = vec3(0.0,0.0,1.0);
displacement = vec3(0.0,0.0,0.0);
displacement += gerstner_wave(wave1,wave1_dir,wave1_t,global_vertex,TANGENT,BINORMAL);
displacement += gerstner_wave(wave2,wave2_dir,wave2_t,global_vertex,TANGENT,BINORMAL);
displacement += gerstner_wave(wave3,wave3_dir,wave3_t,global_vertex,TANGENT,BINORMAL);
VERTEX += displacement;
NORMAL = normalize(cross(BINORMAL,TANGENT));
}
float get_depth(vec2 coords, sampler2D tex, mat4 proj)
{
float depth = texture(tex, coords).r;
vec3 depth_coords_clip = vec3(coords, depth);
depth_coords_clip = depth_coords_clip * 2.0 - 1.0;
vec4 depth_coords_view = proj * vec4(depth_coords_clip,1.0);
depth_coords_view.xyz /= depth_coords_view.w;
depth = -depth_coords_view.z;
return depth;
}
const float pi = 3.1415;
const float tau = pi * 2.0;
float wave_position(float k,vec2 dir,float t)
{
float pos = k * (dot(normalize(dir),global_vertex.xz)-t);
pos = mod(pos-pi,tau);
pos = clamp(pos,0.0,tau);
pos = 1.0 - (0.5*cos(0.159*pow(pos,2.0))+0.5);
return pos;
}
void fragment()
{
ALPHA = 1.0;
SPECULAR = 0.4;
ROUGHNESS = 0.05;
NORMALMAP = texture(noise, UV + (TIME * vec2(-1.0,0.0) * 0.05)).xyz;
NORMALMAP_DEPTH = 0.3;
float depth = get_depth(SCREEN_UV, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
float water_depth = -VERTEX.z;
float submersion = depth - water_depth;
float wave_pos = wave_position(wave1.y,wave1_dir,wave1_t);
wave_pos *= wave_position(wave2.y,wave2_dir,wave2_t);
wave_pos *= wave_position(wave3.y,wave3_dir,wave3_t);
wave_pos = 1.0 - (pow(1.0 - wave_pos, foam_amount_crest));
vec4 foam = texture(foam_map, UV + (-displacement.xz * 0.001));
vec4 mapped_foam_color = mix(water_color,foam_color,foam.b);
vec4 color = mix(water_color, mapped_foam_color, wave_pos);
float object_foam = clamp((foam_amount_edge - submersion) / foam_amount_edge, 0.0, 1.0);
ALBEDO = mix(color, vec4(1.0), object_foam).rgb;
vec3 oriented_normalmap = vec3(TANGENT*NORMALMAP.x + NORMAL*NORMALMAP.y + BINORMAL*NORMALMAP.z);
vec3 normal = normalize(mix(NORMAL,oriented_normalmap,NORMALMAP_DEPTH));
vec2 refraction_uv = SCREEN_UV + (normal.xz * (refraction_amount / exp(water_depth/20.0)));
float murky = murkiness * ROUGHNESS;
depth = get_depth(refraction_uv, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
submersion = depth - water_depth;
murky *= submersion;
float depth_visibility = 0.0;
if(submersion >= 0.0)
{
depth_visibility = exp(-murky);
depth_visibility = clamp(depth_visibility,0.0,1.0);
}
float depth_scatter = exp(murky);
vec4 bg_color = textureLod(SCREEN_TEXTURE, refraction_uv, depth_scatter);
EMISSION = mix(color, bg_color, depth_visibility).rgb * (1.0 - color.a);
}
|