mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-02 02:06:41 +00:00
Add optional shadow map max distance and fading
This commit is contained in:
parent
b700c98e8f
commit
b6ed2f1718
9 changed files with 67 additions and 6 deletions
|
@ -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…
Reference in a new issue