mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 09:39:44 +00:00
Refraction fog based on water depth (feature 5926)
This commit is contained in:
parent
66b2d428c8
commit
525dee00f1
4 changed files with 26 additions and 3 deletions
|
@ -187,6 +187,7 @@ Programmers
|
|||
pkubik
|
||||
PLkolek
|
||||
PlutonicOverkill
|
||||
Qlonever
|
||||
Radu-Marius Popovici (rpopovici)
|
||||
Rafael Moura (dhustkoder)
|
||||
Randy Davin (Kindi)
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
Feature #3537: Shader-based water ripples
|
||||
Feature #5173: Support for NiFogProperty
|
||||
Feature #5492: Let rain and snow collide with statics
|
||||
Feature #5926: Refraction based on water depth
|
||||
Feature #6149: Dehardcode Lua API_REVISION
|
||||
Feature #6152: Playing music via lua scripts
|
||||
Feature #6188: Specular lighting from point light sources
|
||||
|
|
|
@ -114,7 +114,10 @@ namespace MWRender
|
|||
}
|
||||
|
||||
// move the plane back along its normal a little bit to prevent bleeding at the water shore
|
||||
const float clipFudge = -5;
|
||||
float fov = Settings::camera().mFieldOfView;
|
||||
const float clipFudgeMin = 2.5; // minimum offset of clip plane
|
||||
const float clipFudgeScale = -15000.0;
|
||||
float clipFudge = abs(abs((*mCullPlane)[3]) - eyePoint.z()) * fov / clipFudgeScale - clipFudgeMin;
|
||||
modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * clipFudge);
|
||||
|
||||
cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
// tweakables -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
|
||||
const float VISIBILITY = 2500.0;
|
||||
const float VISIBILITY_DEPTH = VISIBILITY * 1.5;
|
||||
const float DEPTH_FADE = 0.15;
|
||||
|
||||
const float BIG_WAVES_X = 0.1; // strength of big waves
|
||||
const float BIG_WAVES_Y = 0.1;
|
||||
|
@ -48,6 +50,7 @@ const float SUN_SPEC_FADING_THRESHOLD = 0.15; // visibility at which sun s
|
|||
const float SPEC_HARDNESS = 256.0; // specular highlights hardness
|
||||
|
||||
const float BUMP_SUPPRESS_DEPTH = 300.0; // at what water depth bumpmap will be suppressed for reflections and refractions (prevents artifacts at shores)
|
||||
const float REFR_FOG_DISTORT_DISTANCE = 3000.0; // at what distance refraction fog will be calculated using real water depth instead of distorted depth (prevents splotchy shores)
|
||||
|
||||
const vec2 WIND_DIR = vec2(0.5f, -0.8f);
|
||||
const float WIND_SPEED = 0.2f;
|
||||
|
@ -160,9 +163,10 @@ void main(void)
|
|||
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
|
||||
#if REFRACTION
|
||||
float depthSample = linearizeDepth(sampleRefractionDepthMap(screenCoords), near, far) * radialise;
|
||||
float depthSampleDistorted = linearizeDepth(sampleRefractionDepthMap(screenCoords-screenCoordsOffset), near, far) * radialise;
|
||||
float surfaceDepth = linearizeDepth(gl_FragCoord.z, near, far) * radialise;
|
||||
float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum
|
||||
float depthSampleDistorted = linearizeDepth(sampleRefractionDepthMap(screenCoords - screenCoordsOffset), near, far) * radialise;
|
||||
float waterDepthDistorted = max(depthSampleDistorted - surfaceDepth, 0.0);
|
||||
screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1);
|
||||
#endif
|
||||
// reflection
|
||||
|
@ -185,6 +189,16 @@ void main(void)
|
|||
// no alpha here, so make sure raindrop ripple specularity gets properly subdued
|
||||
rainSpecular *= clamp(fresnel*6.0 + specular * sunSpec.a, 0.0, 1.0);
|
||||
|
||||
// selectively nullify screenCoordsOffset to eliminate remaining shore artifacts, not needed for reflection
|
||||
if (cameraPos.z > 0.0 && realWaterDepth <= VISIBILITY_DEPTH && waterDepthDistorted > VISIBILITY_DEPTH)
|
||||
screenCoordsOffset = vec2(0.0);
|
||||
|
||||
depthSampleDistorted = linearizeDepth(sampleRefractionDepthMap(screenCoords - screenCoordsOffset), near, far) * radialise;
|
||||
waterDepthDistorted = max(depthSampleDistorted - surfaceDepth, 0.0);
|
||||
|
||||
// fade to realWaterDepth at a distance to compensate for physically inaccurate depth calculation
|
||||
waterDepthDistorted = mix(waterDepthDistorted, realWaterDepth, min(surfaceDepth / REFR_FOG_DISTORT_DISTANCE, 1.0));
|
||||
|
||||
// refraction
|
||||
vec3 refraction = sampleRefractionMap(screenCoords - screenCoordsOffset).rgb;
|
||||
vec3 rawRefraction = refraction;
|
||||
|
@ -193,7 +207,11 @@ void main(void)
|
|||
if (cameraPos.z < 0.0)
|
||||
refraction = clamp(refraction * 1.5, 0.0, 1.0);
|
||||
else
|
||||
refraction = mix(refraction, waterColor, clamp(depthSampleDistorted/VISIBILITY, 0.0, 1.0));
|
||||
{
|
||||
float depthCorrection = sqrt(1.0 + 4.0 * DEPTH_FADE * DEPTH_FADE);
|
||||
float factor = DEPTH_FADE * DEPTH_FADE / (-0.5 * depthCorrection + 0.5 - waterDepthDistorted / VISIBILITY) + 0.5 * depthCorrection + 0.5;
|
||||
refraction = mix(refraction, waterColor, clamp(factor, 0.0, 1.0));
|
||||
}
|
||||
|
||||
// sunlight scattering
|
||||
// normal for sunlight scattering
|
||||
|
|
Loading…
Reference in a new issue