1
0
forked from 0ad/0ad

Removes additional depth texture copying and reusing existing refraction depth.

Tested By: Stan, wraitii
Differential Revision: https://code.wildfiregames.com/D3084
This was SVN commit r24160.
This commit is contained in:
Vladislav Belov 2020-11-11 18:46:52 +00:00
parent 3392330ee9
commit 9669b5f1a9
7 changed files with 47 additions and 60 deletions

View File

@ -218,14 +218,6 @@
"config": "waterfancyeffects",
"function": "Renderer_SetWaterFancyEffectsEnabled"
},
{
"type": "boolean",
"label": "Real water depth",
"tooltip": "Use actual water depth in rendering calculations.",
"dependencies": ["watereffects"],
"config": "waterrealdepth",
"function": "Renderer_SetWaterRealDepthEnabled"
},
{
"type": "boolean",
"label": "Water reflections",
@ -242,6 +234,14 @@
"config": "waterrefraction",
"function": "Renderer_SetWaterRefractionEnabled"
},
{
"type": "boolean",
"label": "Real water depth",
"tooltip": "Use actual water depth in rendering calculations.",
"dependencies": ["watereffects", "waterrefraction"],
"config": "waterrealdepth",
"function": "Renderer_SetWaterRealDepthEnabled"
},
{
"type": "boolean",
"label": "Shadows on water",

View File

@ -59,11 +59,11 @@ uniform vec4 waveParams2; // Smallintensity, Smallbase, Bigmovement, Smallmoveme
#if USE_REFRACTION
uniform sampler2D refractionMap;
#endif
#if USE_REAL_DEPTH
uniform sampler2D depthTex;
uniform float zNear;
uniform float zFar;
uniform mat4 projInvTransform;
uniform mat4 viewInvTransform;
#endif
#endif
#if USE_SHADOWS_ON_WATER && USE_SHADOW
@ -213,24 +213,31 @@ vec4 getReflection(vec3 normal, vec3 eyeVec)
return vec4(reflColor, reflMod);
}
#if USE_REFRACTION && USE_REAL_DEPTH
vec3 getWorldPositionFromRefractionDepth(vec2 uv)
{
float depth = texture2D(depthTex, uv).x;
vec4 viewPosition = projInvTransform * (vec4((uv - vec2(0.5)) * 2.0, depth * 2.0 - 1.0, 1.0));
viewPosition /= viewPosition.w;
vec3 refrWorldPos = (viewInvTransform * viewPosition).xyz;
// Depth buffer precision errors can give heights above the water.
refrWorldPos.y = min(refrWorldPos.y, worldPos.y);
return refrWorldPos;
}
#endif
vec4 getRefraction(vec3 normal, vec3 eyeVec, float depthLimit)
{
float depth;
#if USE_REAL_DEPTH
#if USE_REFRACTION && USE_REAL_DEPTH
// Compute real depth at the target point.
float water_b = gl_FragCoord.z;
float water_n = 2.0 * water_b - 1.0;
float waterDBuffer = 2.0 * zNear * zFar / (zFar + zNear - water_n * (zFar - zNear));
float undisto_z_b = texture2D(depthTex, (gl_FragCoord.xy) / screenSize).x;
float undisto_z_n = 2.0 * undisto_z_b - 1.0;
float waterDepth_undistorted = (2.0 * zNear * zFar / (zFar + zNear - undisto_z_n * (zFar - zNear)) - waterDBuffer);
vec2 coords = (0.5 * refractionCoords.xy) / refractionCoords.z + 0.5;
vec3 refrWorldPos = getWorldPositionFromRefractionDepth(coords);
// Set depth to the depth at the undistorted point.
depth = waterDepth_undistorted;
float depth = distance(refrWorldPos, worldPos);
#else
// fake depth computation: take the value at the vertex, add some if we are looking at a more oblique angle.
depth = waterDepth / (min(0.5, eyeVec.y) * 1.5 * min(0.5, eyeVec.y) * 2.0);
float depth = waterDepth / (min(0.5, eyeVec.y) * 1.5 * min(0.5, eyeVec.y) * 2.0);
#endif
#if USE_REFRACTION
@ -243,10 +250,10 @@ vec4 getRefraction(vec3 normal, vec3 eyeVec, float depthLimit)
float distoFactor = 0.5 + clamp(depth / 2.0, 0.0, 7.0);
#if USE_REAL_DEPTH
vec2 depthCoord = clamp((gl_FragCoord.xy) / screenSize - normal.xz * distoFactor / refractionCoords.z, 0.001, 0.999);
float z_b = texture2D(depthTex, depthCoord).x;
float z_n = 2.0 * z_b - 1.0;
float newDepth = (2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)) - waterDBuffer);
// Distort the texture coords under where the water is to simulate refraction.
vec2 shiftedCoords = (0.5 * refractionCoords.xy - normal.xz * distoFactor) / refractionCoords.z + 0.5;
vec3 refrWorldPos2 = getWorldPositionFromRefractionDepth(shiftedCoords);
float newDepth = distance(refrWorldPos2, worldPos);
// try to correct for fish. In general they'd look weirder without this fix.
if (depth > newDepth + 3.0)
@ -269,7 +276,7 @@ vec4 getRefraction(vec3 normal, vec3 eyeVec, float depthLimit)
// If we get a pure red fragment, use an undistorted/less distorted coord instead.
// blur the refraction map, distoring using normal so that it looks more random than it really is
// and thus looks much better.
float blur = (0.3 + clamp(normal.x, -0.1, 0.1)) / refractionCoords.z;
float blur = (0.1 + clamp(normal.x, -0.1, 0.1)) / refractionCoords.z;
vec4 blurColor = vec4(refColor, 1.0);

View File

@ -123,6 +123,7 @@ X(particle)
X(particle_solid)
X(playerColor)
X(pointSize)
X(projInvTransform)
X(qualityLevel)
X(reflectionMap)
X(reflectionMatrix)
@ -152,6 +153,7 @@ X(time)
X(tint)
X(transform)
X(translation)
X(viewInvTransform)
X(water_simple)
X(waterEffectsTex)
X(waterTex)

View File

@ -1102,6 +1102,8 @@ void CRenderer::RenderRefractions(const CShaderDefines& context, const CBounding
// Save the model-view-projection matrix so the shaders can use it for projective texturing
wm.m_RefractionMatrix = m_ViewCamera.GetViewProjection();
wm.m_RefractionProjInvMatrix = m_ViewCamera.GetProjection().GetInverse();
wm.m_RefractionViewInvMatrix = m_ViewCamera.GetOrientation();
float vpHeight = wm.m_RefTextureSize;
float vpWidth = wm.m_RefTextureSize;

View File

@ -685,28 +685,6 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture();
// creating the real depth texture using the depth buffer.
if (WaterMgr->m_WaterRealDepth)
{
if (WaterMgr->m_depthTT == 0)
{
GLuint depthTex;
glGenTextures(1, (GLuint*)&depthTex);
WaterMgr->m_depthTT = depthTex;
glBindTexture(GL_TEXTURE_2D, WaterMgr->m_depthTT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, g_Renderer.GetWidth(), g_Renderer.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
}
else
{
glBindTexture(GL_TEXTURE_2D, WaterMgr->m_depthTT);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, g_Renderer.GetWidth(), g_Renderer.GetHeight(), 0);
}
glBindTexture(GL_TEXTURE_2D, 0);
}
// Calculating the advanced informations about Foam and all if the quality calls for it.
/*if (WaterMgr->m_NeedInfoUpdate && (WaterMgr->m_WaterFoam || WaterMgr->m_WaterCoastalWaves))
{
@ -769,8 +747,12 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
m->fancyWaterShader->BindTexture(str_waterEffectsTex, WaterMgr->m_FancyTexture);
}
if (WaterMgr->m_WaterRealDepth)
m->fancyWaterShader->BindTexture(str_depthTex, WaterMgr->m_depthTT);
if (WaterMgr->m_WaterRefraction && WaterMgr->m_WaterRealDepth)
{
m->fancyWaterShader->BindTexture(str_depthTex, WaterMgr->m_RefrFboDepthTexture);
m->fancyWaterShader->Uniform(str_projInvTransform, WaterMgr->m_RefractionProjInvMatrix);
m->fancyWaterShader->Uniform(str_viewInvTransform, WaterMgr->m_RefractionViewInvMatrix);
}
if (WaterMgr->m_WaterRefraction)
m->fancyWaterShader->BindTexture(str_refractionMap, WaterMgr->m_RefractionTexture);
@ -809,11 +791,6 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
m->fancyWaterShader->Uniform(str_losMatrix, losTexture.GetTextureMatrix());
m->fancyWaterShader->Uniform(str_cameraPos, camera.GetOrientation().GetTranslation());
if (WaterMgr->m_WaterRealDepth)
{
m->fancyWaterShader->Uniform(str_zNear, camera.GetNearPlane());
m->fancyWaterShader->Uniform(str_zFar, camera.GetFarPlane());
}
m->fancyWaterShader->Uniform(str_fogColor, lightEnv.m_FogColor);
m->fancyWaterShader->Uniform(str_fogParams, lightEnv.m_FogFactor, lightEnv.m_FogMax, 0.f, 0.f);

View File

@ -124,7 +124,6 @@ WaterManager::WaterManager()
m_NeedsReloading = false;
m_NeedInfoUpdate = true;
m_depthTT = 0;
m_FancyTexture = 0;
m_FancyTextureDepth = 0;
m_ReflFboDepthTexture = 0;
@ -160,7 +159,6 @@ WaterManager::~WaterManager()
if (!g_Renderer.GetCapabilities().m_PrettyWater)
return;
glDeleteTextures(1, &m_depthTT);
glDeleteTextures(1, &m_FancyTexture);
glDeleteTextures(1, &m_FancyTextureDepth);
glDeleteTextures(1, &m_ReflFboDepthTexture);
@ -725,7 +723,7 @@ void WaterManager::CreateWaveMeshes()
WaveObject* shoreWave = new WaveObject;
std::vector<SWavesVertex> vertices;
vertices.reserve(9*width);
shoreWave->m_Width = width;
shoreWave->m_TimeDiff = diff;
diff += (rand() % 100) / 25.0f + 4.0f;

View File

@ -61,7 +61,6 @@ public:
CTexturePtr m_WaveTex;
CTexturePtr m_FoamTex;
GLuint m_depthTT;
GLuint m_FancyTexture;
GLuint m_FancyTextureDepth;
GLuint m_ReflFboDepthTexture;
@ -113,6 +112,8 @@ public:
// (used to let the vertex shader do projective texturing)
CMatrix3D m_ReflectionMatrix;
CMatrix3D m_RefractionMatrix;
CMatrix3D m_RefractionProjInvMatrix;
CMatrix3D m_RefractionViewInvMatrix;
// Water parameters
std::wstring m_WaterType; // Which texture to use.