1
1
forked from 0ad/0ad

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.
This commit is contained in:
wraitii 2013-08-24 14:12:39 +00:00
parent aa95f3420d
commit 957c51727b
2 changed files with 46 additions and 19 deletions

View File

@ -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

View File

@ -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)