Ticket #3781: water.diff
File water.diff, 17.7 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/shaders/glsl/water_high.fs
127 127 } 128 128 129 129 void main() 130 { 131 //gl_FragColor = texture2D(waterEffectsTex, gl_FragCoord.xy/screenSize); 132 //return; 133 130 { 134 131 float fresnel; 135 float t; // Temporary variable136 132 vec2 reflCoords, refrCoords; 137 133 vec3 reflColor, refrColor, specular; 138 float losMod ;134 float losMod, reflMod; 139 135 140 vec3 l = -sunDir;141 136 vec3 v = normalize(cameraPos - worldPos); 142 vec3 h = normalize(l + v);143 137 144 138 // Calculate water normals. 145 139 … … 147 141 float baseScale = waveParams1.g; 148 142 float flattenism = waveParams1.b; 149 143 float baseBump = waveParams1.a; 150 151 float smallIntensity = waveParams2.r;152 float smallBase = waveParams2.g;153 144 float BigMovement = waveParams2.b; 154 float SmallMovement = waveParams2.a;155 145 156 146 float moddedTime = mod(time * 60.0, 8.0) / 8.0; 157 147 158 148 // This method uses 60 animated water frames. We're blending between each two frames 159 // TODO: could probably have fewer frames thanks to this blending.160 149 // Scale the normal textures by waviness so that big waviness means bigger waves. 161 150 vec3 ww1 = texture2D(normalMap, (normalCoords.st + normalCoords.zw * BigMovement*waviness/10.0) * (baseScale - waviness/wavyEffect)).xzy; 162 151 vec3 ww2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * BigMovement*waviness/10.0) * (baseScale - waviness/wavyEffect)).xzy; … … 165 154 ww1.x = wwInterp.x * WindCosSin.x - wwInterp.z * WindCosSin.y; 166 155 ww1.z = wwInterp.x * WindCosSin.y + wwInterp.z * WindCosSin.x; 167 156 ww1.y = wwInterp.y; 168 169 vec3 smallWW = texture2D(normalMap, (normalCoords.st + normalCoords.zw * SmallMovement*waviness/10.0) * baseScale*3.0).xzy;170 vec3 smallWW2 = texture2D(normalMap2, (normalCoords.st + normalCoords.zw * SmallMovement*waviness/10.0) * baseScale*3.0).xzy;171 vec3 smallWWInterp = mix(smallWW, smallWW2, moddedTime) - vec3(0.5,0.0,0.5);172 173 smallWW.x = smallWWInterp.x * WindCosSin.x - smallWWInterp.z * WindCosSin.y;174 smallWW.z = smallWWInterp.x * WindCosSin.y + smallWWInterp.z * WindCosSin.x;175 smallWW.y = smallWWInterp.y;176 177 ww1 += vec3(smallWW)*(fwaviness/10.0*smallIntensity + smallBase);178 179 ww1 = mix(smallWW, ww1, waterInfo.r);180 157 181 158 // Flatten them based on waviness. 182 159 vec3 n = normalize(mix(vec3(0.0,1.0,0.0),ww1, clamp(baseBump + fwaviness/flattenism,0.0,1.0))); … … 189 166 n = mix(vec3(0.0,1.0,0.0), n,0.5 + waterInfo.r/2.0); 190 167 #endif 191 168 192 n = vec3(-n.x,n.y,-n.z); 169 n = vec3(-n.x,n.y,-n.z); // The final wave normal vector. 193 170 194 // simulates how parallel the "point->sun", "view->point" vectors are. 195 float ndoth = dot(n , h); 196 197 // how perpendicular to the normal our view is. Used for fresnel. 171 // How perpendicular to the normal our view is. Used for fresnel. 198 172 float ndotv = clamp(dot(n, v),0.0,1.0); 199 173 200 // diffuse lighting-like. used for shadows?201 f loat ndotl = (dot(n, l) + 1.0)/2.0;174 // Fresnel for "how much reflection vs how much refraction". 175 fresnel = clamp(((pow(1.1 - ndotv, 3.0)) * 1.5), 0.2, 1.0); // Approximation. I'm using 1.1 and not 1.0 because it causes artifacts, see #1714 202 176 177 // Specular lighting vectors 178 vec3 specVector = normalize(reflect(sunDir, n)); 179 float specIntensity = pow(abs(dot(specVector, v)), 256.0); 180 181 specular = specIntensity * sunColor * fresnel; 182 203 183 float depth; 204 184 #if USE_REAL_DEPTH 205 185 // Don't change these two. They should match the values in the config (TODO: dec uniforms). … … 238 218 depth = max(depth,fancyeffects.a); 239 219 #endif 240 220 241 // Fresnel for "how much reflection vs how much refraction".242 // Since we're not trying to simulate a realistic ocean 100%, aim for something that gives a little too much reflection243 // because we're not used to seeing the see from above.244 fresnel = clamp(pow(1.05 - ndotv, 1.1),0.0,0.8); // approximation. I'm using 1.05 and not 1.0 because it causes artifacts, see #1714245 // multiply by v.y so that in the distance refraction wins.246 // TODO: this is a hack because reflections don't work in the distance.247 fresnel = clamp(fresnel*1.5,0.0,0.9);248 fresnel *= min(1.0,log(1.0 + v.y*5.0));249 250 //gl_FragColor = vec4(fresnel,fresnel,fresnel,1.0);251 //return;252 253 221 #if USE_SHADOWS_ON_WATER && USE_SHADOW 254 222 float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); 255 223 #endif … … 256 224 257 225 // for refraction, we want to adjust the value by v.y slightly otherwise it gets too different between "from above" and "from the sides". 258 226 // And it looks weird (again, we are not used to seeing water from above). 259 float fixedVy = max(v.y,0. 1);227 float fixedVy = max(v.y,0.01); 260 228 261 float distoFactor = clamp(depth/2.0,0.0,7.0);262 263 229 float murky = mix(200.0,0.1,pow(murkiness,0.25)); 264 230 265 231 #if USE_REFRACTION 266 refrCoords = clamp( (0.5*refractionCoords.xy - n.xz * distoFactor*7.0) / refractionCoords.z + 0.5,0.0,1.0); // Unbias texture coords 232 // distoFactor controls the amount of distortion relative to wave normals. 233 const float distoFactor = 3.5; 234 235 // Distort the texture coords under where the water is to simulate refraction. 236 refrCoords = (0.5 * refractionCoords.xy - n.xz * distoFactor) / refractionCoords.z + 0.5; 267 237 vec3 refColor = texture2D(refractionMap, refrCoords).rgb; 268 if (refColor.r > refColor.g + refColor.b + 0.25) 238 239 // Note, the refraction map is cleared using (255, 0, 0), so pixels outside of the water plane are pure red. 240 // If we get a pure red fragment, use an undistorted/less distorted coord instead. 241 if (refColor.r == 1.0) 269 242 { 270 refrCoords = clamp( (0.5*refractionCoords.xy + n.xz) / refractionCoords.z + 0.5,0.0,1.0); // Unbias texture coords243 refrCoords = (0.5*refractionCoords.xy) / refractionCoords.z + 0.5; 271 244 refColor = texture2D(refractionMap, refrCoords).rgb; 272 245 } 273 246 274 // TODO: make murkiness (both types rematter on that. 275 // linearly extinct the water. This is how quickly we see nothing but the pure water color 247 // Apply water tint and murk color. 276 248 float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); 277 // This is how tinted the water is, ie how quickly the refracted floor takes the tint of the water278 249 float ColextFact = max(0.0,1.0 - (depth*fixedVy/murky)); 279 250 vec3 colll = mix(refColor*tint,refColor,ColextFact); 280 251 281 #if USE_SHADOWS_ON_WATER && USE_SHADOW282 // TODO:283 252 refrColor = mix(color, colll, extFact); 284 253 #else 254 // Apply water tint and murk color only. 255 float extFact = max(0.0,1.0 - (depth*fixedVy/murky)); 256 float ColextFact = max(0.0,1.0 - (depth*fixedVy/murky)); 257 vec3 colll = mix(color*tint,color,ColextFact); 258 285 259 refrColor = mix(color, colll, extFact); 286 260 #endif 287 #else288 // linearly extinct the water. This is how quickly we see nothing but the pure water color289 float extFact = max(0.0,1.0 - (depth*fixedVy/20.0));290 // using both those factors, get our transparency.291 // This will be our base transparency on top.292 float base = 0.4 + depth*fixedVy/15.0; // TODO: murkiness.293 float alphaCoeff = mix(1.0, base, extFact);294 refrColor = color;295 #endif296 261 297 262 #if USE_REFLECTION 298 263 // Reflections 299 // we use real reflections against thskybox, and distort a texture of objects closer.264 // We use real reflections against the skybox, and distort a texture of objects closer. 300 265 vec3 eye = reflect(v,n); 301 //eye.y = min(-0.2,eye.y);302 // let's calculate where we intersect with the skycube.266 267 // Calculate where we intersect with the skycube. 303 268 Ray myRay = Ray(vec3(worldPos.x/4.0,worldPos.y,worldPos.z/4.0),eye); 304 269 vec3 start = vec3(-1500.0 + mapSize/2.0,-100.0,-1500.0 + mapSize/2.0); 305 270 vec3 end = vec3(1500.0 + mapSize/2.0,500.0,1500.0 + mapSize/2.0); 306 271 float tmin = IntersectBox(myRay,start,end); 307 272 vec4 newpos = vec4(-worldPos.x/4.0,worldPos.y,-worldPos.z/4.0,1.0) + vec4(eye * tmin,0.0) - vec4(-mapSize/2.0,worldPos.y,-mapSize/2.0,0.0); 308 //newpos = normalize(newpos);309 273 newpos *= skyBoxRot; 310 274 newpos.y *= 4.0; 311 275 reflColor = textureCube(skyCube, newpos.rgb).rgb; 312 313 // Reflections appear more distorted when viewed from a lower angle. Simulate this.314 float angleEffect = clamp(1.3 - dot(vec3(0.0,1.0,0.0), v),0.0,1.0);315 276 316 reflCoords = clamp( (0.5*reflectionCoords.xy - 40.0 * n.zx * angleEffect) / reflectionCoords.z + 0.5,0.0,1.0); // Unbias texture coords 277 // Distort the reflection coords based on waves. 278 reflCoords = (0.5*reflectionCoords.xy - 15.0 * n.zx) / reflectionCoords.z + 0.5; 317 279 vec4 refTex = texture2D(reflectionMap, reflCoords); 318 fresnel = clamp(fresnel+refTex.a/3.0,0.0,1.0);319 reflColor = refTex.rgb * refTex.a + reflColor*(1.0-refTex.a);320 280 281 // Interpolate between the sky color and nearby objects. 282 reflColor = mix(reflColor.rgb, refTex.rgb, refTex.a); 283 // reflMod is used to reduce the intensity of sky reflections, which otherwise are too extreme. 284 reflMod = max(refTex.a, 0.55); 285 321 286 #else 322 // Temp fix for some ATI cards (see irc logs on th 1st of august betwee, fexor and wraitii)323 //reflCoords = clamp( (0.5*reflectionCoords.xy - waviness * mix(1.0, 20.0,waviness/10.0) * n.zx) / reflectionCoords.z + 0.5,0.0,1.0); // Unbias texture coords324 //vec3 refTex = texture2D(reflectionMap, reflCoords).rgb;325 //reflColor = refTex.rgb;326 287 reflColor = vec3(0.15, 0.7, 0.82); 327 288 #endif 328 289 329 // TODO: At very low angles the reflection stuff doesn't really work any more:330 // IRL you would get a blur of the sky, but we don't have that precision (would require mad oversampling)331 // So tend towards a predefined color (per-map) which looks like what the skybox would look like if you really blurred it.332 // The TODO here would be to precompute a band (1x32?) that represents the average color around the map.333 // TODO: another issue is that at high distances (half map) the texture blurs into flatness. Using better mipmaps won't really solve it334 // So we'll need to stop showing reflections and default to sky color there too.335 // Unless maybe waviness is so low that you would see like in a mirror anyways.336 //float disttt = distance(worldPos,cameraPos);337 //reflColor = mix(vec3(0.5,0.5,0.55), reflColor, clamp(1.0-disttt/600.0*disttt/600.0,0.0,1.0));//clamp(-0.05 + v.y*20.0,0.0,1.0));338 339 // Specular.340 specular = pow(ndoth, mix(5.0,2000.0, clamp(v.y*v.y*2.0,0.0,1.0)))*sunColor * 1.5;// * sunColor * 1.5 * ww.r;341 342 290 losMod = texture2D(losMap, losCoords.st).a; 343 291 losMod = losMod < 0.03 ? 0.0 : losMod; 344 292 345 float wavesFresnel = 1.0;346 347 #if USE_FANCY_EFFECTS348 wavesFresnel = mix(1.0-fancyeffects.a,1.0,clamp(depth,0.0,1.0));349 #endif350 351 293 vec3 color; 352 294 #if USE_SHADOWS_ON_WATER && USE_SHADOW 353 295 float fresShadow = mix(fresnel, fresnel*shadow, 0.05 + murkiness*0.2); 354 color = mix(refrColor, reflColor, fresShadow * wavesFresnel);296 color = mix(refrColor, reflColor, fresShadow); 355 297 #else 356 color = mix(refrColor, reflColor, fresnel * wavesFresnel);298 color = mix(refrColor, reflColor, fresnel * reflMod); 357 299 #endif 358 300 359 301 #if USE_SHADOWS_ON_WATER && USE_SHADOW … … 373 315 foaminterp *= mix(foam3, foam4, moddedTime); 374 316 375 317 foam1.x = foaminterp.x * WindCosSin.x - foaminterp.z * WindCosSin.y; 376 //foam1.z = foaminterp.x * WindCosSin.y + foaminterp.z * WindCosSin.x; 377 //foam1.y = foaminterp.y; 318 378 319 float foam = FoamEffects.r * FoamEffects.a*0.4 + pow(foam1.x*(5.0+waviness),(2.6 - waviness/5.5)); 379 foam *= ndotl;380 320 381 gl_FragColor.rgb = get_fog(color) * losMod + foam * losMod; // + fancyeffects.a * losMod;321 gl_FragColor.rgb = get_fog(color) * losMod + foam * losMod; 382 322 #else 383 323 gl_FragColor.rgb = get_fog(color) * losMod; 384 324 #endif 385 325 386 #if !USE_REFRACTION 387 gl_FragColor.a = clamp(depth*2.0,0.0,1.0) * alphaCoeff; 388 #else 389 gl_FragColor.a = clamp(depth*5.0,0.0,1.0); 390 #endif 326 gl_FragColor.a = 1.0; 391 327 392 328 #if USE_FANCY_EFFECTS 393 329 if (fancyeffects.a < 0.05 && waterDepth < -1.0 ) 394 330 gl_FragColor.a = 0.0; 395 331 #endif 396 397 //gl_FragColor = vec4(sunColor,1.0);398 332 } -
source/renderer/Renderer.cpp
1119 1119 camera.ClipFrustum(CVector4D(0, 1, 0, -wm.m_WaterHeight)); 1120 1120 1121 1121 SViewPort vp; 1122 vp.m_Height = wm.m_Ref lectionTextureSize;1123 vp.m_Width = wm.m_Ref lectionTextureSize;1122 vp.m_Height = wm.m_RefTextureSize; 1123 vp.m_Width = wm.m_RefTextureSize; 1124 1124 vp.m_X = 0; 1125 1125 vp.m_Y = 0; 1126 1126 camera.SetViewPort(vp); … … 1155 1155 camera.ClipFrustum(CVector4D(0, -1, 0, wm.m_WaterHeight + 0.5f)); // add some to avoid artifacts near steep shores. 1156 1156 1157 1157 SViewPort vp; 1158 vp.m_Height = wm.m_Ref ractionTextureSize;1159 vp.m_Width = wm.m_Ref ractionTextureSize;1158 vp.m_Height = wm.m_RefTextureSize; 1159 vp.m_Width = wm.m_RefTextureSize; 1160 1160 vp.m_X = 0; 1161 1161 vp.m_Y = 0; 1162 1162 camera.SetViewPort(vp); … … 1188 1188 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1189 1189 wm.m_ReflectionMatrix = m_ViewCamera.GetViewProjection(); 1190 1190 1191 float vpHeight = wm.m_Ref lectionTextureSize;1192 float vpWidth = wm.m_Ref lectionTextureSize;1191 float vpHeight = wm.m_RefTextureSize; 1192 float vpWidth = wm.m_RefTextureSize; 1193 1193 1194 1194 SScreenRect screenScissor; 1195 1195 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vpWidth); … … 1271 1271 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1272 1272 wm.m_RefractionMatrix = m_ViewCamera.GetViewProjection(); 1273 1273 1274 float vpHeight = wm.m_Ref ractionTextureSize;1275 float vpWidth = wm.m_Ref ractionTextureSize;1274 float vpHeight = wm.m_RefTextureSize; 1275 float vpWidth = wm.m_RefTextureSize; 1276 1276 1277 1277 SScreenRect screenScissor; 1278 1278 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vpWidth); -
source/renderer/WaterManager.cpp
91 91 92 92 m_ReflectionTexture = 0; 93 93 m_RefractionTexture = 0; 94 m_ReflectionTextureSize = 0; 95 m_RefractionTextureSize = 0; 94 m_RefTextureSize = 0; 96 95 97 96 m_ReflectionFbo = 0; 98 97 m_RefractionFbo = 0; … … 236 235 m_FoamTex = texture; 237 236 } 238 237 239 m_ReflectionTextureSize = g_Renderer.GetHeight() * 0.66; // Higher settings give a better result240 m_Ref ractionTextureSize = g_Renderer.GetHeight() * 0.33; // Lower settings actually sorta look better since it blurs.238 // Use screen-sized textures for minimum artifacts. 239 m_RefTextureSize = g_Renderer.GetHeight(); 241 240 242 if (round_down_to_pow2(m_ReflectionTextureSize)/m_ReflectionTextureSize < 0.65) 243 m_ReflectionTextureSize = round_up_to_pow2(m_ReflectionTextureSize); 244 else 245 m_ReflectionTextureSize = round_down_to_pow2(m_ReflectionTextureSize); 241 m_RefTextureSize = round_up_to_pow2(m_RefTextureSize); 246 242 247 if (round_down_to_pow2(m_RefractionTextureSize)/m_RefractionTextureSize < 0.7)248 m_RefractionTextureSize = round_up_to_pow2(m_RefractionTextureSize);249 else250 m_RefractionTextureSize = round_down_to_pow2(m_RefractionTextureSize);251 252 243 // Create reflection texture 253 244 glGenTextures(1, &m_ReflectionTexture); 254 245 glBindTexture(GL_TEXTURE_2D, m_ReflectionTexture); … … 256 247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 257 248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); 258 249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); 259 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_Ref lectionTextureSize, (GLsizei)m_ReflectionTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);250 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 260 251 261 252 // Create refraction texture 262 253 glGenTextures(1, &m_RefractionTexture); … … 265 256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 266 257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); 267 258 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); 268 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, (GLsizei)m_Ref ractionTextureSize, (GLsizei)m_RefractionTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);259 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 269 260 270 261 // Create depth textures 271 262 glGenTextures(1, &m_ReflFboDepthTexture); … … 274 265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 275 266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 276 267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 277 glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_Ref lectionTextureSize, (GLsizei)m_ReflectionTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);268 glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); 278 269 279 270 glGenTextures(1, &m_RefrFboDepthTexture); 280 271 glBindTexture(GL_TEXTURE_2D, m_RefrFboDepthTexture); … … 282 273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 283 274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 284 275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 285 glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_Ref ractionTextureSize, (GLsizei)m_RefractionTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);276 glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); 286 277 287 278 // Create the Fancy Effects texture 288 279 glGenTextures(1, &m_FancyTextureNormal); -
source/renderer/WaterManager.h
103 103 // Reflection and refraction textures for fancy water 104 104 GLuint m_ReflectionTexture; 105 105 GLuint m_RefractionTexture; 106 size_t m_ReflectionTextureSize; 107 size_t m_RefractionTextureSize; 106 size_t m_RefTextureSize; 108 107 109 108 // framebuffer objects 110 109 GLuint m_RefractionFbo;