1// This shader is mostly an adaptation of the shader found at 2// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion 3// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10 4// � Michael Horsch - 2005 5// Major update and revisions - 2011-10-07 6// � Emilian Huminiuc and Vivian Meazza 7// Optimisation - 2012-5-05 8// Based on ideas by Thorsten Renk 9// � Emilian Huminiuc and Vivian Meazza 10 11#version 120 12 13uniform sampler2D perlin_normalmap; 14uniform sampler2D sea_foam; 15uniform sampler2D water_dudvmap; 16uniform sampler2D water_normalmap; 17uniform sampler2D water_reflection; 18uniform sampler2D water_reflection_grey; 19 20uniform float CloudCover0; 21uniform float CloudCover1; 22uniform float CloudCover2; 23uniform float CloudCover3; 24uniform float CloudCover4; 25uniform float Overcast; 26uniform float WaveAmp; 27uniform float WaveFreq; 28uniform float WaveSharp; 29uniform float WindE; 30uniform float WindN; 31uniform float normalmap_dds; 32uniform float osg_SimulationTime; 33uniform float saturation; 34 35uniform int Status; 36 37varying vec3 lightdir; 38varying vec3 normal; 39varying vec3 viewerdir; 40varying vec4 waterTex1; //moving texcoords 41varying vec4 waterTex2; //moving texcoords 42 43 44////fog "include" ///// 45uniform int fogType; 46 47vec3 fog_Func(vec3 color, int type); 48////////////////////// 49 50/////// functions ///////// 51 52void rotationmatrix(in float angle, out mat4 rotmat) 53 { 54 rotmat = mat4( cos( angle ), -sin( angle ), 0.0, 0.0, 55 sin( angle ), cos( angle ), 0.0, 0.0, 56 0.0 , 0.0 , 1.0, 0.0, 57 0.0 , 0.0 , 0.0, 1.0 ); 58 } 59 60void main(void) 61 { 62 const vec4 sca = vec4(0.005, 0.005, 0.005, 0.005); 63 const vec4 sca2 = vec4(0.02, 0.02, 0.02, 0.02); 64 const vec4 tscale = vec4(0.25, 0.25, 0.25, 0.25); 65 66 mat4 RotationMatrix; 67 // compute direction to viewer 68 vec3 E = normalize(viewerdir); 69 70 // compute direction to light source 71 vec3 L = normalize(lightdir); 72 73 // half vector 74 vec3 H = normalize(L + E); 75 76 vec3 Normal = normalize(normal); 77 78 const float water_shininess = 240.0; 79 80 // approximate cloud cover 81 float cover = 0.0; 82 //bool Status = true; 83 84 85 float windEffect = sqrt( WindE*WindE + WindN*WindN ) * 0.6; //wind speed in kt 86 float windScale = 15.0/(3.0 + windEffect); //wave scale 87 float windEffect_low = 0.3 + 0.7 * smoothstep(0.0, 5.0, windEffect); //low windspeed wave filter 88 float waveRoughness = 0.05 + smoothstep(0.0, 20.0, windEffect); //wave roughness filter 89 90 float mixFactor = 0.75 - 0.15 * smoothstep(0.0, 40.0, windEffect); 91 mixFactor = clamp(mixFactor, 0.3, 0.8); 92 93 if (Status == 1){ 94 cover = min(min(min(min(CloudCover0, CloudCover1),CloudCover2),CloudCover3),CloudCover4); 95 } else { 96 // hack to allow for Overcast not to be set by Local Weather 97 if (Overcast == 0.0){ 98 cover = 5.0; 99 } else { 100 cover = Overcast * 5.0; 101 } 102 } 103 104 vec4 viewt = vec4(-E, 0.0) * 0.6; 105 106 vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)* windScale) * 2.0 - 1.0; 107 108 vec4 dist = texture2D(water_dudvmap, vec2(waterTex1 + disdis*sca2)* windScale) * 2.0 - 1.0; 109 dist *= (0.6 + 0.5 * smoothstep(0.0, 15.0, windEffect)); 110 vec4 fdist = normalize(dist); 111 if (normalmap_dds > 0) 112 fdist = -fdist; //dds fix 113 fdist *= sca; 114 115 //normalmaps 116 rotationmatrix(radians(3.0 * windScale + 0.6 * sin(waterTex1.s * 0.2)), RotationMatrix); 117 vec4 nmap = texture2D(water_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale) * 2.0 - 1.0; 118 vec4 nmap1 = texture2D(perlin_normalmap, vec2(waterTex1/** RotationMatrix*/ + disdis * sca2) * windScale) * 2.0 - 1.0; 119 120 rotationmatrix(radians(-2.0 * windScale -0.4 * sin(waterTex1.s * 0.32)), RotationMatrix); 121 nmap += texture2D(water_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale * 1.5) * 2.0 - 1.0; 122 //nmap1 += texture2D(perlin_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale) * 2.0 - 1.0; 123 rotationmatrix(radians(1.5 * windScale + 0.3 * sin(waterTex1.s * 0.16)), RotationMatrix); 124 nmap += texture2D(water_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale * 2.1) * 2.0 - 1.0; 125 rotationmatrix(radians(-0.5 * windScale - 0.45 * sin(waterTex1.s * 0.28)), RotationMatrix); 126 nmap += texture2D(water_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale * 0.8) * 2.0 - 1.0; 127 128 rotationmatrix(radians(-1.2 * windScale - 0.35 * sin(waterTex1.s * 0.28)), RotationMatrix); 129 nmap += texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix* tscale) * windScale * 1.7) * 2.0 - 1.0; 130 nmap1 += texture2D(perlin_normalmap, vec2(waterTex2/** RotationMatrix*/ * tscale) * windScale) * 2.0 - 1.0; 131 132 nmap *= windEffect_low; 133 nmap1 *= windEffect_low; 134 // mix water and noise, modulated by factor 135 vec4 vNorm = normalize(mix(nmap, nmap1, mixFactor) * waveRoughness); 136 if (normalmap_dds > 0) 137 vNorm = -vNorm; //dds fix 138 139 //load reflection 140 vec4 tmp = vec4(lightdir, 0.0); 141 vec4 refTex = texture2D(water_reflection, vec2(tmp + waterTex1) * 32.0) ; 142 vec4 refTexGrey = texture2D(water_reflection_grey, vec2(tmp + waterTex1) * 32.0) ; 143 vec4 refl ; 144 145 // cover = 0; 146 147 if(cover >= 1.5){ 148 refl = normalize(refTex); 149 refl.a = 1.0; 150 } 151 else 152 { 153 refl = normalize(refTexGrey); 154 refl.r *= (0.75 + 0.15 * cover); 155 refl.g *= (0.80 + 0.15 * cover); 156 refl.b *= (0.875 + 0.125 * cover); 157 refl.a = 1.0; 158 } 159 160 rotationmatrix(radians(2.1* windScale + 0.25 * sin(waterTex1.s *0.14)), RotationMatrix); 161 vec3 N0 = vec3(texture2D(water_normalmap, vec2(waterTex1* RotationMatrix + disdis * sca2) * windScale * 1.15) * 2.0 - 1.0); 162 vec3 N1 = vec3(texture2D(perlin_normalmap, vec2(waterTex1/** RotationMatrix*/ + disdis * sca) * windScale) * 2.0 - 1.0); 163 164 rotationmatrix(radians(-1.5 * windScale -0.32 * sin(waterTex1.s *0.24)), RotationMatrix); 165 N0 += vec3(texture2D(water_normalmap, vec2(waterTex2* RotationMatrix * tscale) * windScale * 1.8) * 2.0 - 1.0); 166 N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex2/** RotationMatrix*/ * tscale) * windScale) * 2.0 - 1.0); 167 168 rotationmatrix(radians(3.8 * windScale + 0.45 * sin(waterTex1.s *0.32)), RotationMatrix); 169 N0 += vec3(texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix * (tscale + sca2)) * windScale * 0.85) * 2.0 - 1.0); 170 N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex2/** RotationMatrix*/ * (tscale + sca2)) * windScale) * 2.0 - 1.0); 171 172 rotationmatrix(radians(-2.8 * windScale - 0.38 * sin(waterTex1.s * 0.26)), RotationMatrix); 173 N0 += vec3(texture2D(water_normalmap, vec2(waterTex1 * RotationMatrix + disdis * sca2) * windScale * 2.1) * 2.0 - 1.0); 174 N1 += vec3(texture2D(perlin_normalmap, vec2(waterTex1 /** RotationMatrix*/ + disdis * sca) * windScale) * 2.0 - 1.0); 175 176 N0 *= windEffect_low; 177 N1 *= windEffect_low; 178 179 vec3 N = normalize(mix(Normal + N0, Normal + N1, mixFactor) * waveRoughness); 180 181 if (normalmap_dds > 0) 182 N = -N; //dds fix 183 184 // specular 185 vec3 specular_color = vec3(gl_LightSource[0].diffuse) 186 * pow(max(0.0, dot(N, H)), water_shininess) * 6.0; 187 vec4 specular = vec4(specular_color, 0.5); 188 189 specular = specular * saturation * 0.3 ; 190 191 //calculate fresnel 192 vec4 invfres = vec4( dot(vNorm, viewt) ); 193 vec4 fres = vec4(1.0) + invfres; 194 refl *= fres; 195 196 //calculate final colour 197 vec4 ambient_light = gl_LightSource[0].diffuse; 198 vec4 finalColor; 199 200 if(cover >= 1.5){ 201 finalColor = refl + specular; 202 } else { 203 finalColor = refl; 204 } 205 206 float foamSlope = 0.10 + 0.1 * windScale; 207 208 vec4 foam_texel = texture2D(sea_foam, vec2(waterTex2 * tscale) * 25.0); 209 float waveSlope = N.g; 210 211 if (windEffect >= 8.0) 212 if (waveSlope >= foamSlope){ 213 finalColor = mix(finalColor, max(finalColor, finalColor + foam_texel), smoothstep(0.01, 0.50, N.g)); 214 } 215 216 217 finalColor *= ambient_light; 218 219 //gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor); 220 finalColor.rgb = fog_Func(finalColor.rgb, fogType); 221 gl_FragColor = finalColor; 222 } 223