1
0
forked from 0ad/0ad

Fix "Wind Angle" parameter not working properly. Add a precomputed "wind strength" variable so that waves look smaller behind islands. Some tweaks. Refs #48 as usual.

This was SVN commit r15492.
This commit is contained in:
wraitii 2014-07-05 10:20:30 +00:00
parent aa99f98fce
commit 5571f7a7f9
6 changed files with 79 additions and 38 deletions

View File

@ -6,7 +6,9 @@
uniform float waviness;
uniform vec2 screenSize;
uniform float time;
varying vec3 worldPos;
varying vec4 waterInfo;
uniform float mapSize;
@ -23,7 +25,8 @@ uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmoveme
void main()
{
float wavyFactor = waviness * 0.125;
// Fix the waviness for local wind strength
float fwaviness = waviness * ((0.15+waterInfo.r/1.15));
float wavyEffect = waveParams1.r;
float baseScale = waveParams1.g;
@ -46,9 +49,12 @@ void main()
ww1 = mix(ww1, ww2, mod(time * 60.0, 8.0) / 8.0);
smallWW = mix(smallWW, smallWW2, mod(time * 60.0, 8.0) / 8.0) - vec3(0.5);
ww1 += vec3(smallWW.x,0.0,smallWW.z)*(waviness/10.0*smallIntensity + smallBase);
ww1 += vec3(smallWW.x,0.0,smallWW.z)*(fwaviness/10.0*smallIntensity + smallBase);
vec3 n = normalize(mix(vec3(0.0,1.0,0.0),ww1 - vec3(0.5,0.0,0.5), clamp(baseBump + waviness/flattenism,0.0,1.0)));
ww1 = mix(smallWW + vec3(0.5,0.0,0.5), ww1, waterInfo.r);
// Flatten them based on waviness.
vec3 n = normalize(mix(vec3(0.0,1.0,0.0),ww1 - vec3(0.5,0.0,0.5), clamp(baseBump + fwaviness/flattenism,0.0,1.0)));
float foamFact1 = texture2D(normalMap, (gl_TexCoord[0].st) * 0.3).a;
float foamFact2 = texture2D(normalMap2, (gl_TexCoord[0].st) * 0.3).a;

View File

@ -2,20 +2,29 @@
// This is a lightened version of water_high.vs
uniform float repeatScale;
uniform vec2 translation;
uniform float windAngle;
uniform float time;
uniform float mapSize;
varying vec3 worldPos;
varying vec4 waterInfo;
attribute vec3 a_vertex;
attribute vec4 a_waterInfo;
void main()
{
worldPos = a_vertex;
waterInfo = a_waterInfo;
float newX = a_vertex.x * cos(-windAngle) - a_vertex.z * sin(-windAngle);
float newY = a_vertex.x * sin(-windAngle) + a_vertex.z * cos(-windAngle);
gl_TexCoord[0] = vec4(newX,newY,time,0.0);
gl_TexCoord[0].xy *= repeatScale;
gl_TexCoord[0] = vec4(a_vertex.xz*repeatScale,translation);
gl_TexCoord[3].zw = vec2(a_vertex.xz)/mapSize;
gl_Position = gl_ModelViewProjectionMatrix * vec4(a_vertex, 1.0);

View File

@ -33,11 +33,11 @@ uniform sampler2D normalMap2;
#if USE_FANCY_EFFECTS
uniform sampler2D waterEffectsTex;
#else
uniform vec4 waveParams1; // wavyEffect, BaseScale, Flattenism, Basebump
uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmovement
#endif
uniform vec4 waveParams1; // wavyEffect, BaseScale, Flattenism, Basebump
uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmovement
#if USE_REFLECTION
uniform sampler2D reflectionMap;
#endif
@ -128,6 +128,9 @@ vec3 get_fog(vec3 color)
void main()
{
//gl_FragColor = vec4(waterInfo.rrr,1.0);
//return;
float fresnel;
float t; // Temporary variable
vec2 reflCoords, refrCoords;
@ -139,7 +142,7 @@ void main()
vec3 h = normalize(l + v);
// Fix the waviness for local wind strength
float fwaviness = 6.0;waviness;// * ((0.15+waterInfo.r/1.15));
float fwaviness = waviness * ((0.15+waterInfo.r/1.15));
// Calculate water normals.
#if USE_FANCY_EFFECTS
@ -155,7 +158,7 @@ void main()
float smallBase = waveParams2.g;
float BigMovement = waveParams2.b;
float SmallMovement = waveParams2.a;
// This method uses 60 animated water frames. We're blending between each two frames
// TODO: could probably have fewer frames thanks to this blending.
// Scale the normal textures by waviness so that big waviness means bigger waves.
@ -167,17 +170,22 @@ void main()
ww1 = mix(ww1, ww2, mod(time * 60.0, 8.0) / 8.0);
smallWW = mix(smallWW, smallWW2, mod(time * 60.0, 8.0) / 8.0) - vec3(0.5);
ww1 += vec3(smallWW.x,0.0,smallWW.z)*(waviness/10.0*smallIntensity + smallBase);
ww1 += vec3(smallWW.x,0.0,smallWW.z)*(fwaviness/10.0*smallIntensity + smallBase);
ww1 = mix(smallWW + vec3(0.5,0.0,0.5), ww1, waterInfo.r);
// Flatten them based on waviness.
vec3 n = normalize(mix(vec3(0.0,1.0,0.0),ww1 - vec3(0.5,0.0,0.5), clamp(baseBump + waviness/flattenism,0.0,1.0)));
vec3 n = normalize(mix(vec3(0.0,1.0,0.0),ww1 - vec3(0.5,0.0,0.5), clamp(baseBump + fwaviness/flattenism,0.0,1.0)));
// Fix our normals.
//n = normalize(n - vec3(0.5, 0.5, 0.5));
#endif
n = mix(vec3(0.0,1.0,0.0), n,0.5 + waterInfo.r/2.0);
// simulates how parallel the "point->sun", "view->point" vectors are.
float ndoth = dot(n , h);
// how perpendicular to the normal our view is. Used for fresnel.
float ndotv = clamp(dot(n, v),0.0,1.0);
@ -311,7 +319,8 @@ void main()
// Specular.
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;
gl_FragColor = vec4(specular,1.0);
return;
losMod = texture2D(losMap, gl_TexCoord[3].st).a;
losMod = losMod < 0.03 ? 0.0 : losMod;

View File

@ -6,7 +6,6 @@ uniform mat4 losMatrix;
uniform mat4 shadowTransform;
uniform float repeatScale;
uniform float windAngle;
uniform vec2 translation;
uniform float waviness; // "Wildness" of the reflections and refractions; choose based on texture
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
@ -31,7 +30,11 @@ void main()
waterInfo = a_waterInfo;
waterDepth = a_waterInfo.a;
gl_TexCoord[0] = vec4(a_vertex.xz*repeatScale,translation);
float newX = a_vertex.x * cos(-windAngle) - a_vertex.z * sin(-windAngle);
float newY = a_vertex.x * sin(-windAngle) + a_vertex.z * cos(-windAngle);
gl_TexCoord[0] = vec4(newX,newY,time,0.0);
gl_TexCoord[0].xy *= repeatScale;
gl_TexCoord[1] = reflectionMatrix * vec4(a_vertex, 1.0); // projective texturing
gl_TexCoord[2] = refractionMatrix * vec4(a_vertex, 1.0);
gl_TexCoord[3] = losMatrix * vec4(a_vertex, 1.0);

View File

@ -703,13 +703,8 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
double period = 8;
int curTex = (int)(time*60/period) % 60;
int nexTex = (curTex + 1) % 60;
// Shift the texture coordinates by these amounts to make the water "flow"
float tx = time*cos(WaterMgr->m_WindAngle);
float ty = time*sin(WaterMgr->m_WindAngle);
float repeatPeriod = WaterMgr->m_RepeatPeriod;
GLuint FramebufferName = 0;
@ -746,9 +741,9 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
m->fancyEffectsShader->BindTexture(str_normalMap, WaterMgr->m_NormalMap[curTex]);
m->fancyEffectsShader->BindTexture(str_normalMap2, WaterMgr->m_NormalMap[nexTex]);
m->fancyEffectsShader->Uniform(str_waviness, WaterMgr->m_Waviness);
m->fancyEffectsShader->Uniform(str_translation, tx, ty);
m->fancyEffectsShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
m->fancyEffectsShader->Uniform(str_time, (float)time);
m->fancyEffectsShader->Uniform(str_windAngle, (float)WaterMgr->m_WindAngle);
m->fancyEffectsShader->Uniform(str_screenSize, (float)g_Renderer.GetWidth(), (float)g_Renderer.GetHeight(), 0.0f, 0.0f);
m->fancyEffectsShader->Uniform(str_mapSize, (float)(WaterMgr->m_MapSize));
@ -765,7 +760,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
else
{
m->fancyEffectsShader->Uniform(str_waveParams1, 15.0f,0.8f,10.0f,0.1f);
m->fancyEffectsShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.35f);
m->fancyEffectsShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.3f);
}
std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
@ -818,7 +813,6 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
m->fancyWaterShader->Uniform(str_waviness, WaterMgr->m_Waviness);
m->fancyWaterShader->Uniform(str_murkiness, WaterMgr->m_Murkiness);
m->fancyWaterShader->Uniform(str_windAngle, WaterMgr->m_WindAngle);
m->fancyWaterShader->Uniform(str_translation, tx, ty);
m->fancyWaterShader->Uniform(str_repeatScale, 1.0f / repeatPeriod);
m->fancyWaterShader->Uniform(str_reflectionMatrix, WaterMgr->m_ReflectionMatrix);
m->fancyWaterShader->Uniform(str_refractionMatrix, WaterMgr->m_RefractionMatrix);
@ -844,7 +838,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
else
{
m->fancyWaterShader->Uniform(str_waveParams1, 15.0f,0.8f,10.0f,0.1f);
m->fancyWaterShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.35f);
m->fancyWaterShader->Uniform(str_waveParams2, 0.3f,0.0f,0.1f,0.3f);
}
}

View File

@ -379,6 +379,8 @@ void WaterManager::RecomputeBlurredNormalMap()
m_BlurredNormalMap[j*m_MapSize + i] = blurValue * 0.2f;
}
}
delete[] normals;
}
///////////////////////////////////////////////////////////////////
@ -388,24 +390,26 @@ void WaterManager::RecomputeWindStrength()
{
if (m_WindStrength == NULL)
m_WindStrength = new float[m_MapSize*m_MapSize];
std::fill(m_WindStrength, m_WindStrength + m_MapSize*m_MapSize, 1.0f);
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
float waterLevel = m_WaterHeight;
CVector2D windDir = CVector2D(cos(m_WindAngle),sin(m_WindAngle));
CVector2D perp = CVector2D(-windDir.Y, windDir.X);
// Our kernel will sample 5 points going towards the wind (generally).
int kernel[5][2] = { {(int)windDir.X*2,(int)windDir.Y*2}, {(int)windDir.X*5,(int)windDir.Y*5}, {(int)windDir.X*9,(int)windDir.Y*9}, {(int)windDir.X*16,(int)windDir.Y*16}, {(int)windDir.X*25,(int)windDir.Y*25} };
//CVector2D perp = CVector2D(-windDir.Y, windDir.X);
float* Temp = new float[m_MapSize*m_MapSize];
std::fill(Temp, Temp + m_MapSize*m_MapSize, 1.0f);
for (size_t j = 0; j < m_MapSize; ++j)
for (size_t i = 0; i < m_MapSize; ++i)
{
float curHeight = terrain->GetVertexGroundLevel(i,j);
if (curHeight >= waterLevel)
{
m_WindStrength[j*m_MapSize + i] = 0.0f;
Temp[j*m_MapSize + i] = 0.3f; // blurs too strong otherwise
continue;
}
if (terrain->GetVertexGroundLevel(i + ceil(windDir.X),j + ceil(windDir.Y)) < waterLevel)
@ -415,34 +419,50 @@ void WaterManager::RecomputeWindStrength()
float tendency = 0.0f;
float oldHeight = std::max(waterLevel,terrain->GetVertexGroundLevel(i+kernel[4][0],j+kernel[4][1]));
float currentHeight = std::max(waterLevel,terrain->GetVertexGroundLevel(i+kernel[3][0],j+kernel[3][1]));
float avgheight = oldHeight + currentHeight;
tendency = currentHeight - oldHeight;
oldHeight = currentHeight;
currentHeight = std::max(waterLevel,terrain->GetVertexGroundLevel(i+kernel[2][0],j+kernel[2][1]));
avgheight += currentHeight;
tendency += currentHeight - oldHeight;
oldHeight = currentHeight;
currentHeight = std::max(waterLevel,terrain->GetVertexGroundLevel(i+kernel[1][0],j+kernel[1][1]));
avgheight += currentHeight;
tendency += currentHeight - oldHeight;
oldHeight = currentHeight;
currentHeight = std::max(waterLevel,terrain->GetVertexGroundLevel(i+kernel[0][0],j+kernel[0][1]));
avgheight += currentHeight;
tendency += currentHeight - oldHeight;
float baseLevel = std::max(0.0f,1.0f - (currentHeight-waterLevel)/20.0f);
float baseLevel = std::max(0.0f,1.0f - (avgheight/5.0f-waterLevel)/20.0f);
baseLevel *= baseLevel;
tendency /= 10.0f;
tendency /= 15.0f;
baseLevel -= tendency; // if the terrain was sloping downwards, increase baselevel. Otherwise reduce.
baseLevel = clamp(baseLevel,0.0f,1.0f);
// Draw on map. This is pretty slow.
//float width = 3.0f;
float length = 1.2f;//21.0f * (1.0f-baseLevel);
float length = 35.0f * (1.0f-baseLevel/1.8f);
for (float y = 0; y < length; y += 0.6f)
//for (float x = -width*(y+1)/(length+1); x < width*(y+1)/(length+1); x += 0.5f)
{
int index = clamp(j - y * windDir.Y,0.0f,(float)(m_MapSize-1))*m_MapSize + clamp(i - y * windDir.X,0.0f,(float)(m_MapSize-1));
m_WindStrength[index] = (0.5f+baseLevel*0.5f) * (1.0f-y/length) + y/length * 1.0f;
int xx = clamp(i - y * windDir.X,0.0f,(float)(m_MapSize-1));
int yy = clamp(j - y * windDir.Y,0.0f,(float)(m_MapSize-1));
Temp[yy*m_MapSize + xx] = Temp[yy*m_MapSize + xx] < (0.0f+baseLevel/1.5f) * (1.0f-y/length) + y/length * 1.0f ?
Temp[yy*m_MapSize + xx] : (0.0f+baseLevel/1.5f) * (1.0f-y/length) + y/length * 1.0f;
}
}
int blurKernel[4][2] = { {(int)ceil(windDir.X),(int)ceil(windDir.Y)}, {(int)windDir.X*3,(int)windDir.Y*3}, {(int)ceil(perp.X),(int)ceil(perp.Y)}, {(int)-ceil(perp.X),(int)-ceil(perp.Y)} };
float blurValue;
for (size_t j = 2; j < m_MapSize-2; ++j)
for (size_t i = 2; i < m_MapSize-2; ++i)
{
blurValue = Temp[(j+blurKernel[0][1])*m_MapSize + i+blurKernel[0][0]];
blurValue += Temp[(j+blurKernel[0][1])*m_MapSize + i+blurKernel[0][0]];
blurValue += Temp[(j+blurKernel[0][1])*m_MapSize + i+blurKernel[0][0]];
blurValue += Temp[(j+blurKernel[0][1])*m_MapSize + i+blurKernel[0][0]];
m_WindStrength[j*m_MapSize + i] = blurValue * 0.25f;
}
delete[] Temp;
}
////////////////////////////////////////////////////////////////////////