Add optional shadow map max distance and fading

pull/556/head
bzzt 5 years ago committed by Capostrophic
parent b700c98e8f
commit b6ed2f1718

@ -843,6 +843,11 @@ void SceneUtil::MWShadowTechnique::setPolygonOffset(float factor, float units)
}
}
void SceneUtil::MWShadowTechnique::setShadowFadeStart(float shadowFadeStart)
{
_shadowFadeStart = shadowFadeStart;
}
void SceneUtil::MWShadowTechnique::enableFrontFaceCulling()
{
_useFrontFaceCulling = true;
@ -1493,6 +1498,9 @@ void MWShadowTechnique::createShaders()
osg::ref_ptr<osg::Uniform> baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit);
_uniforms.push_back(baseTextureUnit.get());
_uniforms.push_back(new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance()));
_uniforms.push_back(new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart));
for(unsigned int sm_i=0; sm_i<settings->getNumShadowMapsPerLight(); ++sm_i)
{
{

@ -76,6 +76,8 @@ namespace SceneUtil {
virtual void setPolygonOffset(float factor, float units);
virtual void setShadowFadeStart(float shadowFadeStart);
virtual void enableFrontFaceCulling();
virtual void disableFrontFaceCulling();
@ -257,6 +259,8 @@ namespace SceneUtil {
bool _useFrontFaceCulling = true;
float _shadowFadeStart = 0.0;
class DebugHUD : public osg::Referenced
{
public:

@ -27,6 +27,14 @@ namespace SceneUtil
mShadowSettings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight);
mShadowSettings->setBaseShadowTextureUnit(8 - numberOfShadowMapsPerLight);
const float maximumShadowMapDistance = Settings::Manager::getFloat("maximum shadow map distance", "Shadows");
if (maximumShadowMapDistance > 0)
{
const float shadowFadeStart = std::min(std::max(0.f, Settings::Manager::getFloat("shadow fade start", "Shadows")), 1.f);
mShadowSettings->setMaximumShadowMapDistance(maximumShadowMapDistance);
mShadowTechnique->setShadowFadeStart(maximumShadowMapDistance * shadowFadeStart);
}
mShadowSettings->setMinimumShadowMapNearFarRatio(Settings::Manager::getFloat("minimum lispsm near far ratio", "Shadows"));
if (Settings::Manager::getBool("compute tight scene bounds", "Shadows"))
mShadowSettings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
@ -117,6 +125,8 @@ namespace SceneUtil
definesWithShadows["shadowNormalOffset"] = std::to_string(Settings::Manager::getFloat("normal offset distance", "Shadows"));
definesWithShadows["limitShadowMapDistance"] = Settings::Manager::getFloat("maximum shadow map distance", "Shadows") > 0 ? "1" : "0";
return definesWithShadows;
}
@ -138,6 +148,8 @@ namespace SceneUtil
definesWithoutShadows["shadowNormalOffset"] = "0.0";
definesWithoutShadows["limitShadowMapDistance"] = "0";
return definesWithoutShadows;
}

@ -16,7 +16,6 @@ Unlike in the original Morrowind engine, 'Shadow Mapping' is used, which can hav
Bear in mind that this will force OpenMW to use shaders as if :ref:`force shaders` was enabled.
A keen developer may be able to implement compatibility with fixed-function mode using the advice of `this post <https://github.com/OpenMW/openmw/pull/1547#issuecomment-369657381>`_, but it may be more difficult than it seems.
number of shadow maps
---------------------
@ -28,6 +27,28 @@ Control how many shadow maps to use - more of these means each shadow map texel
Using too many shadow maps will lead to them overriding texture slots used for other effects, producing unpleasant artefacts.
A value of three is recommended in most cases, but other values may produce better results or performance.
maximum shadow map distance
---------------------------
:Type: float
:Range: The whole range of 32-bit floating point
:Default: 8192
The maximum distance from the camera shadows cover, limiting their overall area coverage
and improving their quality and performance at the cost of removing shadows of distant objects or terrain.
Set this to a non-positive value to remove the limit.
shadow fade start
-------------------
:Type: float
:Range: 0.0-1.0
:Default: 0.9
The fraction of the maximum shadow map distance at which the shadows will begin to fade away.
Tweaking it will make the transition proportionally more or less smooth.
This setting has no effect if the maximum shadow map distance is non-positive (infinite).
allow shadow map overlap
------------------------
@ -213,4 +234,4 @@ minimum lispsm near far ratio
Controls the minimum near/far ratio for the Light Space Perspective Shadow Map transformation.
Helps prevent too much detail being brought towards the camera at the expense of detail further from the camera.
Increasing this pushes detail further away by moving the frustum apex further from the near plane.
Increasing this pushes detail further away by moving the frustum apex further from the near plane.

@ -746,6 +746,12 @@ enable shadows = false
# How many shadow maps to use - more of these means each shadow map texel covers less area, producing better looking shadows, but may decrease performance.
number of shadow maps = 3
# The distance from the camera at which shadows fade away completely. Set to 0 to make the distance infinite.
maximum shadow map distance = 8192
# Fraction of the maximum distance at which shadows begin to gradually fade away.
shadow fade start = 0.9
# If true, allow shadow maps to overlap. Counter-intuitively, will produce better results when the light is behind the camera. When enabled, OpenMW uses Cascaded Shadow Maps and when disabled, it uses Parallel Split Shadow Maps.
allow shadow map overlap = true

@ -114,7 +114,7 @@ void main()
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
#endif
float shadowing = unshadowedLightRatio();
float shadowing = unshadowedLightRatio(depth);
#if !PER_PIXEL_LIGHTING

@ -1,6 +1,8 @@
#define SHADOWS @shadows_enabled
#if SHADOWS
uniform float maximumShadowMapDistance;
uniform float shadowFadeStart;
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform sampler2DShadow shadowTexture@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@ -11,10 +13,15 @@
@endforeach
#endif // SHADOWS
float unshadowedLightRatio()
float unshadowedLightRatio(float distance)
{
float shadowing = 1.0;
#if SHADOWS
#if @limitShadowMapDistance
float fade = clamp((distance - shadowFadeStart) / (maximumShadowMapDistance - shadowFadeStart), 0.0, 1.0);
if (fade == 1.0)
return shadowing;
#endif
#if @shadowMapsOverlap
bool doneShadows = false;
@foreach shadow_texture_unit_index @shadow_texture_unit_list
@ -41,6 +48,9 @@ float unshadowedLightRatio()
shadowing = min(shadow2DProj(shadowTexture@shadow_texture_unit_index, shadowSpaceCoords@shadow_texture_unit_index).r, shadowing);
@endforeach
#endif
#if @limitShadowMapDistance
shadowing = mix(shadowing, 1.0, fade);
#endif
#endif // SHADOWS
return shadowing;
}

@ -66,7 +66,7 @@ void main()
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
#endif
float shadowing = unshadowedLightRatio();
float shadowing = unshadowedLightRatio(depth);
#if !PER_PIXEL_LIGHTING

@ -160,7 +160,7 @@ void main(void)
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
UV.y *= -1.0;
float shadow = unshadowedLightRatio();
float shadow = unshadowedLightRatio(depthPassthrough);
vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
screenCoords.y = (1.0-screenCoords.y);

Loading…
Cancel
Save