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:
parent
3392330ee9
commit
9669b5f1a9
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user