3
* @file bumpWaterFS.glsl
4
* @brief An extended bumpmapping water shader
7
* Copyright (C) 2008,2009. Licensed under the terms of the
8
* GNU GPL, v2 or later.
12
//////////////////////////////////////////////////
13
// runtime defined constants are:
14
// #define SurfaceColor vec4
15
// #define DiffuseColor vec3
16
// #define PlaneColor vec4 (unused)
17
// #define AmbientFactor float
18
// #define DiffuseFactor float (note: it is the map defined value multipled with 15x!)
19
// #define SpecularColor vec3
20
// #define SpecularPower float
21
// #define SpecularFactor float
22
// #define PerlinStartFreq float
23
// #define PerlinFreq float
24
// #define PerlinAmp float
25
// #define Speed float
26
// #define FresnelMin float
27
// #define FresnelMax float
28
// #define FresnelPower float
29
// #define ScreenInverse vec2
30
// #define ViewPos vec2
31
// #define MapMid vec3
32
// #define SunDir vec3
33
// #define ReflDistortion float
34
// #define BlurBase vec2
35
// #define BlurExponent float
36
// #define PerlinStartFreq float
37
// #define PerlinLacunarity float
38
// #define PerlinAmp float
39
// #define WindSpeed float
40
// #define TexGenPlane vec4
41
// #define ShadingPlane vec4
43
#define CausticDepth 0.5
44
#define CausticRange 0.45
45
#define WavesLength 0.15
48
//////////////////////////////////////////////////
49
// possible flags are:
50
// //#define opt_heightmap
51
// #define opt_reflection
52
// #define opt_refraction
53
// #define opt_shorewaves
55
// #define opt_blurreflection
56
// #define opt_texrect
57
// #define opt_endlessocean
60
#extension GL_ARB_texture_rectangle : enable
62
#define texture2DRect texture2D
63
#define sampler2DRect sampler2D
67
//////////////////////////////////////////////////
68
// Uniforms + Varyings
70
uniform sampler2D normalmap;
71
uniform sampler2D heightmap;
72
uniform sampler2D caustic;
73
uniform sampler2D foam;
74
uniform sampler2D reflection;
75
uniform sampler2DRect refraction;
76
uniform sampler2D coastmap;
77
uniform sampler2DRect depthmap;
78
uniform sampler2D waverand;
85
//////////////////////////////////////////////////
86
// Screen Coordinates (normalized and screen dimensions)
89
vec2 screencoord = (gl_FragCoord.xy - ViewPos);
90
vec2 reftexcoord = (screencoord*ScreenInverse);
92
vec2 screenPos = gl_FragCoord.xy - ViewPos;
93
vec2 screencoord = screenPos*ScreenTextureSizeInverse;
94
vec2 reftexcoord = screenPos*ScreenInverse;
98
//////////////////////////////////////////////////
101
float pm15 = gl_ProjectionMatrix[2][3];
102
float pm11 = gl_ProjectionMatrix[2][3];
103
float convertDepthToZ(float d) {
104
return pm15 / (((d * 2.0) - 1.0) + pm11);
108
//////////////////////////////////////////////////
109
// shorewaves functions
110
#ifdef opt_shorewaves
111
const float InvWavesLength = 1.0/WavesLength;
113
float smoothlimit(const float x, const float step) {
115
//return step * smoothstep(1.0,step,x);
116
return step - (mod(x,step)*step)/(1.0-step);
122
float waveIntensity(const float x) {
123
//float front = smoothstep(1.0-0.85,0.0,abs(x-0.85));
124
float front = 1.0-(abs(x-0.85))/(1.0-0.85);
126
return max(front,x*0.5);
131
vec4 waveIntensity(const vec4 v) {
132
vec4 front = vec4(1.0)-(abs(v - vec4(0.85)))/vec4(1.0-0.85);
134
front.x = max(front.x,v.x*0.5);
136
front.y = max(front.y,v.y*0.5);
138
front.z = max(front.z,v.z*0.5);
140
front.w = max(front.w,v.w*0.5);
146
//////////////////////////////////////////////////
151
vec3 coast = vec3(0.0,0.0,1.0);
152
float waterdepth,invwaterdepth;
153
#ifdef opt_endlessocean
154
if ( any(greaterThanEqual(gl_TexCoord[5].st,ShadingPlane.pq)) ||
155
any(lessThanEqual(gl_TexCoord[5].st,vec2(0.0,0.0)))
163
#ifdef opt_shorewaves
164
coast = texture2D(coastmap,gl_TexCoord[0].st).rgb;
165
if (coast.r==1.0) discard;
166
invwaterdepth = coast.b;
167
waterdepth = 1.0 - invwaterdepth;
169
invwaterdepth = texture2D(heightmap,gl_TexCoord[5].st).a; //heightmap in alpha channel
170
waterdepth = 1.0 - invwaterdepth;
171
if (waterdepth==0.0) discard;
176
float tz = texture2DRect(depthmap, screencoord ).r;
177
float shallowScale = clamp( abs( convertDepthToZ(tz) - convertDepthToZ(gl_FragCoord.z) )/3.0, 0.0,1.0);
179
float shallowScale = waterdepth;
182
gl_FragColor.a = 1.0;
185
vec3 octave1 = texture2D(normalmap,gl_TexCoord[1].st).rgb;
186
vec3 octave2 = texture2D(normalmap,gl_TexCoord[1].pq).rgb;
187
vec3 octave3 = texture2D(normalmap,gl_TexCoord[2].st).rgb;
188
vec3 octave4 = texture2D(normalmap,gl_TexCoord[2].pq).rgb;
190
const float a = PerlinAmp;
191
octave1 = (octave1*2.0-1.0)*a;
192
octave2 = (octave2*2.0-1.0)*a*a;
193
octave3 = (octave3*2.0-1.0)*a*a*a;
194
octave4 = (octave4*2.0-1.0)*a*a*a*a;
196
vec3 normal = octave1+octave2+octave3+octave4;
197
normal = normalize( normal ).xzy;
199
vec3 eVec = normalize(eyeVec);
200
float eyeNormalCos = dot(-eVec, normal);
201
float angle = (1.0-abs(eyeNormalCos));
205
vec3 reflectDir = reflect(normalize(-ligVec), normal);
206
float specular = angle * pow( max(dot(reflectDir,eVec), 0.0) , SpecularPower) * SpecularFactor * shallowScale;
207
const vec3 SunLow = SunDir * vec3(1.0,0.1,1.0);
208
float diffuse = pow( max( dot(normal,SunLow) ,0.0 ) ,3.0)*DiffuseFactor;
209
float ambient = smoothstep(-1.3,0.0,eyeNormalCos)*AmbientFactor;
210
vec3 waterSurface = SurfaceColor.rgb + DiffuseColor*diffuse + vec3(ambient);
211
float surfaceMix = (SurfaceColor.a + diffuse)*shallowScale;
212
float refractDistortion = 60.0*(1.0-pow(gl_FragCoord.z,80.0))*shallowScale;
216
#ifdef opt_refraction
218
vec3 refrColor = texture2DRect(refraction, screencoord + normal.xz*refractDistortion ).rgb;
220
vec3 refrColor = texture2DRect(refraction, screencoord + normal.xz*refractDistortion*ScreenInverse ).rgb;
222
gl_FragColor.rgb = mix(refrColor,waterSurface, 0.1+surfaceMix);
224
gl_FragColor.rgb = waterSurface;
225
gl_FragColor.a = surfaceMix + specular;
230
if (waterdepth>0.0) {
231
vec3 caust = texture2D(caustic,gl_TexCoord[0].pq*75.0).rgb;
232
#ifdef opt_refraction
233
float caustBlend = smoothstep(CausticRange,0.0,abs(waterdepth-CausticDepth));
234
gl_FragColor.rgb += caust*caustBlend*0.08;
236
gl_FragColor.a *= min(waterdepth*4.0,1.0);
237
gl_FragColor.rgb += caust*(1.0-waterdepth)*0.6;
243
#ifdef opt_shorewaves
244
float coastdist = coast.g + octave3.x*0.1;
246
vec3 wavefoam = texture2D(foam, gl_TexCoord[3].st ).rgb;
247
wavefoam += texture2D(foam, gl_TexCoord[3].pq ).rgb;
250
if (waterdepth<1.0) {
251
vec4 waverands = texture2D(waverand, gl_TexCoord[4].pq);
255
for (int i=0; i<4; i++) {
256
f[i] = fract(fi + frame * 50.0);
260
f -= vec4(coastdist);
261
f = vec4(1.0) - f * InvWavesLength;
262
f = clamp( f ,0.0,1.0);
263
f = waveIntensity(f);
264
vec3 shorewavesColor = wavefoam * dot(f,waverands) * coastdist;
266
float iwd = smoothlimit(invwaterdepth, 0.8);
267
gl_FragColor.rgb += shorewavesColor * iwd * 1.5;
271
gl_FragColor.rgb += 5.5 * (wavefoam * wavefoam) * (coast.r * coast.r * coast.r) * (coastdist * coastdist * coastdist * coastdist);
277
#ifdef opt_reflection
278
//we have to mirror the Y-axis
279
reftexcoord = vec2(reftexcoord.x,1.0 - reftexcoord.y);
280
reftexcoord += vec2(0.0,3.0*ScreenInverse.y) + normal.xz*0.09*ReflDistortion;
282
vec3 reflColor = texture2D(reflection,reftexcoord).rgb;
284
#ifdef opt_blurreflection
285
const vec2 v = BlurBase;
286
const float s = BlurExponent;
287
reflColor += texture2D(reflection,reftexcoord.st+v).rgb;
288
reflColor += texture2D(reflection,reftexcoord.st+v*s).rgb;
289
reflColor += texture2D(reflection,reftexcoord.st+v*s*s).rgb;
290
reflColor += texture2D(reflection,reftexcoord.st+v*s*s*s).rgb;
291
reflColor += texture2D(reflection,reftexcoord.st+v*s*s*s*s).rgb;
292
reflColor += texture2D(reflection,reftexcoord.st+v*s*s*s*s*s).rgb;
293
reflColor += texture2D(reflection,reftexcoord.st+v*s*s*s*s*s*s).rgb;
297
float fresnel = FresnelMin + FresnelMax * pow(angle,FresnelPower);
298
gl_FragColor.rgb = mix(gl_FragColor.rgb, reflColor, fresnel*shallowScale);
303
gl_FragColor.rgb += specular*SpecularColor;
306
float fog = clamp( (gl_Fog.end - abs(gl_FogFragCoord)) * gl_Fog.scale ,0.0,1.0);
307
gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fog );