From 957c51727b1d6ecdbf8602d958bc3df90390a339 Mon Sep 17 00:00:00 2001 From: wraitii Date: Sat, 24 Aug 2013 14:12:39 +0000 Subject: [PATCH] Improve on-water shadows. Fix an issue with foam looking static. Add anisotropic filtering (x4) to the water normal texture for testing. This was SVN commit r13750. --- .../mods/public/shaders/glsl/water_high.fs | 36 ++++++++++++------- source/renderer/WaterManager.cpp | 29 +++++++++++---- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/binaries/data/mods/public/shaders/glsl/water_high.fs b/binaries/data/mods/public/shaders/glsl/water_high.fs index 7c70b83414..248851b41c 100644 --- a/binaries/data/mods/public/shaders/glsl/water_high.fs +++ b/binaries/data/mods/public/shaders/glsl/water_high.fs @@ -101,6 +101,7 @@ void main() float distToShore = heightmapval.b; #endif + vec3 n, l, h, v; // Normal, light vector, half-vector and view vector (vector to eye) float ndotl, ndoth, ndotv; float fresnel; @@ -137,7 +138,7 @@ void main() #endif ndotl = (dot(n, l) + 1.0)/2.0; - ndotv = dot(n, v); + ndotv = clamp(dot(n, v),0.0,1.0); #if USE_REAL_DEPTH // Don't change these two. They should match the values in the config (TODO: dec uniforms). @@ -182,11 +183,11 @@ void main() // texture is not rotated, moves twice faster in the opposite direction, translated. vec2 foam2RC = gl_TexCoord[0].st*1.8 + vec2(time*-0.019,time*-0.012) - 0.012*n.xz + vec2(0.4,0.2); - vec2 WaveRocking = cos(time*1.2566) * beachOrientation * clamp(1.0 - distToShore,0.1,1.0)/6.0; + vec2 WaveRocking = cos(time*1.2566) * beachOrientation * clamp(1.0 - distToShore,0.1,1.0)/3.0; vec4 foam1 = texture2D(Foam, foam1RC + vec2(-WaveRocking.t,WaveRocking.s)); vec4 foam2 = foam1.r*texture2D(Foam, foam2RC + WaveRocking); - vec3 finalFoam = min((foam2).rrr * waterInfo.a,1.0); + vec3 finalFoam = min((foam2).rrr * waterInfo.a,1.0); if ((1.0 - finalFoam.r) >= wavyFactor) finalFoam = vec3(0.0); @@ -196,21 +197,33 @@ void main() #endif finalFoam *= sunColor; #endif - + + #if USE_SHADOWS && USE_SHADOW + float shadow = get_shadow(vec4(v_shadow.xy, v_shadow.zw)); + #endif + #if USE_REFRACTION #if USE_REAL_DEPTH refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords vec3 refColor = texture2D(refractionMap, refrCoords).rgb; float luminance = (1.0 - clamp((waterDepth2/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0)); float colorExtinction = clamp(waterDepth2*murkiness/5.0,0.0,1.0); - refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #if USE_SHADOWS && USE_SHADOW + refrColor = (0.5 + 0.5*ndotl) * mix(color * (0.5 + shadow/2.0),mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #else + refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #endif #else refrCoords = clamp( (0.5*gl_TexCoord[2].xy - n.xz * distoFactor) / gl_TexCoord[2].w + 0.5,0.0,1.0); // Unbias texture coords // cleverly get the perceived depth based on camera tilting (if horizontal, it's likely we will have more water to look at). vec3 refColor = texture2D(refractionMap, refrCoords).rgb; float luminance = (1.0 - clamp((perceivedDepth/mix(300.0,1.0, pow(murkiness,0.2) )), 0.0, 1.0)); float colorExtinction = clamp(perceivedDepth*murkiness/5.0,0.0,1.0); - refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #if USE_SHADOWS && USE_SHADOW + refrColor = (0.5 + 0.5*ndotl) * mix(color * (0.5 + shadow/2.0),mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #else + refrColor = (0.5 + 0.5*ndotl) * mix(color,mix(refColor,refColor*tint,colorExtinction),luminance*luminance); + #endif #endif #else float alphaCoeff = 0.0; @@ -238,9 +251,9 @@ void main() #endif #if USE_NORMALS - specular = pow(ndoth, mix(50.0,450.0, v.y*2.0)) * sunColor * 1.5; + specular = pow(ndoth, mix(100.0,450.0, v.y*2.0)) * sunColor * 1.5; #else - specular = pow(ndoth, mix(50.0,450.0, v.y*2.0)) * sunColor * 1.5 * ww.r; + specular = pow(ndoth, mix(100.0,450.0, v.y*2.0)) * sunColor * 1.5 * ww.r; #endif losMod = texture2D(losMap, gl_TexCoord[3].st).a; @@ -248,12 +261,11 @@ void main() vec3 colour; #if USE_SHADOWS && USE_SHADOW - float shadow = get_shadow(vec4(v_shadow.xy - 8.0*waviness*n.xz, v_shadow.zw)); - float fresShadow = mix(fresnel, fresnel*shadow, 0.05 + (murkiness * 0.15)); + float fresShadow = mix(fresnel, fresnel*shadow, 0.05 + murkiness*0.2); #if USE_FOAM - colour = mix(refrColor*(shadow/5.0 + 0.8), reflColor, fresShadow) + max(ndotl,0.4)*(finalFoam)*(shadow/2.0 + 0.5); + colour = mix(refrColor, reflColor, fresShadow) + max(ndotl,0.4)*(finalFoam)*(shadow/2.0 + 0.5); #else - colour = mix(refrColor*(shadow/5.0 + 0.8), reflColor, fresShadow); + colour = mix(refrColor, reflColor, fresShadow); #endif #else #if USE_FOAM diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index c66e32f9ab..1e260f4b08 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -157,7 +157,8 @@ int WaterManager::LoadWaterTextures() swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal%02d.dds", water_type, (int)i+1); CTextureProperties textureProps(pathname); textureProps.SetWrap(GL_REPEAT); - + textureProps.SetMaxAnisotropy(4); + CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); texture->Prefetch(); m_NormalMap[i] = texture; @@ -197,8 +198,8 @@ int WaterManager::LoadWaterTextures() 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // Create refraction texture glGenTextures(1, &m_RefractionTexture); @@ -267,10 +268,10 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation) m_WaterHeight = cmpWaterManager->GetExactWaterLevel(0,0); // Get the square we want to work on. - i32 Xstart = clamp(m_updatei0, 0, (i32)m_MapSize); - i32 Xend = clamp(m_updatei1, 0, (i32)m_MapSize); - i32 Zstart = clamp(m_updatej0, 0, (i32)m_MapSize); - i32 Zend = clamp(m_updatej1, 0, (i32)m_MapSize); + i32 Xstart = clamp(m_updatei0, 0, (i32)m_MapSize-1); + i32 Xend = clamp(m_updatei1, 0, (i32)m_MapSize-1); + i32 Zstart = clamp(m_updatej0, 0, (i32)m_MapSize-1); + i32 Zend = clamp(m_updatej1, 0, (i32)m_MapSize-1); if (m_WaveX == NULL) { @@ -290,6 +291,20 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation) // this might be updated to actually cache in the terrain manager but that's not for now. CVector3D* normals = new CVector3D[m_MapSize*m_MapSize]; + + // taken out of the bottom loop, blurs the normal map + // To remove if below is reactivated + ssize_t blurZstart = Zstart-4 < 0 ? 0 : Zstart - 4; + ssize_t blurZend = Zend+4 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : Zend + 4; + ssize_t blurXstart = Xstart-4 < 0 ? 0 : Xstart - 4; + ssize_t blurXend = Xend+4 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : Xend + 4; + for (ssize_t j = blurZstart; j < blurZend; ++j) + { + for (ssize_t i = blurXstart; i < blurXend; ++i) + { + normals[j*m_MapSize + i] = terrain->CalcExactNormal(((float)i)*4.0f,((float)j)*4.0f); + } + } // TODO: reactivate? /* // calculate wave force (not really used right now)