From c3e0398d1c93962ed2f4b5a79afb37032de50fb3 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 27 Dec 2017 02:32:17 +0000 Subject: [PATCH] Add settings --- apps/openmw/mwrender/characterpreview.cpp | 9 +-- apps/openmw/mwrender/localmap.cpp | 9 +-- apps/openmw/mwrender/renderingmanager.cpp | 29 +++----- apps/openmw/mwrender/sky.cpp | 3 +- components/sceneutil/shadow.cpp | 89 +++++++++++++++++------ components/sceneutil/shadow.hpp | 15 ++-- files/settings-default.cfg | 19 +++++ 7 files changed, 107 insertions(+), 66 deletions(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 15cc63893..e329d9ebc 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -151,14 +151,7 @@ namespace MWRender defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); stateset->setAttribute(defaultMat); - osg::ref_ptr fakeShadowMapImage = new osg::Image(); - fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT); - *(float*)fakeShadowMapImage->data() = std::numeric_limits::infinity(); - osg::ref_ptr fakeShadowMapTexture = new osg::Texture2D(fakeShadowMapImage); - fakeShadowMapTexture->setShadowComparison(true); - fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS); - for (int i = SceneUtil::MWShadow::baseShadowTextureUnit; i < SceneUtil::MWShadow::baseShadowTextureUnit + SceneUtil::MWShadow::numberOfShadowMapsPerLight; ++i) - stateset->setTextureAttributeAndModes(i, fakeShadowMapTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); + SceneUtil::MWShadow::disableShadowsForStateSet(stateset); // assign large value to effectively turn off fog // shaders don't respect glDisable(GL_FOG) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 7f3132a9e..d4f55f18b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -202,14 +202,7 @@ osg::ref_ptr LocalMap::createOrthographicCamera(float x, float y, f lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - osg::ref_ptr fakeShadowMapImage = new osg::Image(); - fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT); - *(float*)fakeShadowMapImage->data() = std::numeric_limits::infinity(); - osg::ref_ptr fakeShadowMapTexture = new osg::Texture2D(fakeShadowMapImage); - fakeShadowMapTexture->setShadowComparison(true); - fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS); - for (int i = SceneUtil::MWShadow::baseShadowTextureUnit; i < SceneUtil::MWShadow::baseShadowTextureUnit + SceneUtil::MWShadow::numberOfShadowMapsPerLight; ++i) - stateset->setTextureAttributeAndModes(i, fakeShadowMapTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); + SceneUtil::MWShadow::disableShadowsForStateSet(stateset); camera->addChild(lightSource); camera->setStateSet(stateset); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index caa808909..e72149b76 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -204,26 +204,15 @@ namespace MWRender osg::ref_ptr shadowedScene (new osgShadow::ShadowedScene); - osgShadow::ShadowSettings* settings = shadowedScene->getShadowSettings(); - settings->setLightNum(0); - settings->setCastsShadowTraversalMask(Mask_Scene|Mask_Actor|Mask_Player|Mask_Terrain); - settings->setReceivesShadowTraversalMask(~0u); - - //settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::PERSPECTIVE_SHADOW_MAP); - settings->setBaseShadowTextureUnit(SceneUtil::MWShadow::baseShadowTextureUnit); - settings->setMinimumShadowMapNearFarRatio(0.25); - settings->setNumShadowMapsPerLight(SceneUtil::MWShadow::numberOfShadowMapsPerLight); - //settings->setShadowMapProjectionHint(osgShadow::ShadowSettings::ORTHOGRAPHIC_SHADOW_MAP); - //settings->setMultipleShadowMapHint(osgShadow::ShadowSettings::PARALLEL_SPLIT); // ignored - settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); - //settings->setDebugDraw(true); // don't turn this on because it makes everything break - - //settings->setPerspectiveShadowMapCutOffAngle(0); - //settings->setShaderHint(osgShadow::ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER); - - int mapres = 2048; - settings->setTextureSize(osg::Vec2s(mapres,mapres)); - + int shadowCastingTraversalMask = Mask_Scene; + if (Settings::Manager::getBool("actor shadows", "Shadows")) + shadowCastingTraversalMask |= Mask_Actor; + if (Settings::Manager::getBool("player shadows", "Shadows")) + shadowCastingTraversalMask |= Mask_Player; + if (Settings::Manager::getBool("terrain shadows", "Shadows")) + shadowCastingTraversalMask |= Mask_Terrain; + SceneUtil::MWShadow::setupShadowSettings(shadowedScene->getShadowSettings(), shadowCastingTraversalMask); + SceneUtil::MWShadow* tech = new SceneUtil::MWShadow(); shadowedScene->setShadowTechnique(tech); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 331782c7b..79f5f00bb 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1124,8 +1124,7 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana // Assign empty program to specify we don't want shaders // The shaders generated by the SceneManager can't handle everything we need skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::PROTECTED|osg::StateAttribute::ON); - for (int i = SceneUtil::MWShadow::baseShadowTextureUnit; i < SceneUtil::MWShadow::baseShadowTextureUnit + SceneUtil::MWShadow::numberOfShadowMapsPerLight; ++i) - skyroot->getOrCreateStateSet()->setTextureMode(i, GL_TEXTURE_2D, osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF); + SceneUtil::MWShadow::disableShadowsForStateSet(skyroot->getOrCreateStateSet()); skyroot->setNodeMask(Mask_Sky); parentNode->addChild(skyroot); diff --git a/components/sceneutil/shadow.cpp b/components/sceneutil/shadow.cpp index 21a0de89a..0d654a817 100644 --- a/components/sceneutil/shadow.cpp +++ b/components/sceneutil/shadow.cpp @@ -7,6 +7,8 @@ #include #include +#include + namespace SceneUtil { using namespace osgShadow; @@ -46,35 +48,76 @@ namespace SceneUtil " gl_FragColor = vec4( fS + fH * color, 1 ); \n" #else " gl_FragColor = texture2D(texture, gl_TexCoord[0].xy); \n" - " //gl_FragColor = vec4(1.0, 0.5, 0.5, 1.0); \n" #endif "} \n"; - - MWShadow::MWShadow() : debugProgram(new osg::Program), debugTextureUnit(0) + void MWShadow::setupShadowSettings(osg::ref_ptr settings, int castsShadowMask) { - osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX, debugVertexShaderSource); - debugProgram->addShader(vertexShader); - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, debugFragmentShaderSource); - debugProgram->addShader(fragmentShader); + if (!Settings::Manager::getBool("enable shadows", "Shadows")) + return; - for (int i = 0; i < numberOfShadowMapsPerLight; ++i) + settings->setLightNum(0); + settings->setCastsShadowTraversalMask(castsShadowMask); + settings->setReceivesShadowTraversalMask(~0u); + + int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows"); + settings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight); + settings->setBaseShadowTextureUnit(8 - numberOfShadowMapsPerLight); + + settings->setMinimumShadowMapNearFarRatio(0.25); + if (Settings::Manager::getBool("compute tight scene bounds", "Shadows")) + settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); + + int mapres = Settings::Manager::getInt("shadow map resolution", "Shadows"); + settings->setTextureSize(osg::Vec2s(mapres, mapres)); + } + + void MWShadow::disableShadowsForStateSet(osg::ref_ptr stateset) + { + int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows"); + int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight; + + osg::ref_ptr fakeShadowMapImage = new osg::Image(); + fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT); + *(float*)fakeShadowMapImage->data() = std::numeric_limits::infinity(); + osg::ref_ptr fakeShadowMapTexture = new osg::Texture2D(fakeShadowMapImage); + fakeShadowMapTexture->setShadowComparison(true); + fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS); + for (int i = baseShadowTextureUnit; i < baseShadowTextureUnit + numberOfShadowMapsPerLight; ++i) + stateset->setTextureAttributeAndModes(i, fakeShadowMapTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); + } + + MWShadow::MWShadow() : enableShadows(Settings::Manager::getBool("enable shadows", "Shadows")), + numberOfShadowMapsPerLight(Settings::Manager::getInt("number of shadow maps", "Shadows")), + baseShadowTextureUnit(8 - numberOfShadowMapsPerLight), + debugHud(Settings::Manager::getBool("enable debug hud", "Shadows")), + debugProgram(new osg::Program), debugTextureUnit(0) + { + if (debugHud) { - std::cout << i << std::endl; - - debugCameras.push_back(new osg::Camera); - debugCameras[i]->setViewport(200 * i, 0, 200, 200); - debugCameras[i]->setRenderOrder(osg::Camera::POST_RENDER); - debugCameras[i]->setClearColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); - - debugGeometry.push_back(osg::createTexturedQuadGeometry(osg::Vec3(-1, -1, 0), osg::Vec3(2, 0, 0), osg::Vec3(0, 2, 0))); - debugGeometry[i]->setCullingActive(false); - debugCameras[i]->addChild(debugGeometry[i]); - osg::ref_ptr stateSet = debugGeometry[i]->getOrCreateStateSet(); - stateSet->setAttributeAndModes(debugProgram, osg::StateAttribute::ON); - osg::ref_ptr textureUniform = new osg::Uniform("texture", debugTextureUnit); - //textureUniform->setType(osg::Uniform::SAMPLER_2D); - stateSet->addUniform(textureUniform.get()); + osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX, debugVertexShaderSource); + debugProgram->addShader(vertexShader); + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, debugFragmentShaderSource); + debugProgram->addShader(fragmentShader); + + for (int i = 0; i < numberOfShadowMapsPerLight; ++i) + { + std::cout << i << std::endl; + + debugCameras.push_back(new osg::Camera); + debugCameras[i]->setViewport(200 * i, 0, 200, 200); + debugCameras[i]->setRenderOrder(osg::Camera::POST_RENDER); + debugCameras[i]->setClearColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); + + debugGeometry.push_back(osg::createTexturedQuadGeometry(osg::Vec3(-1, -1, 0), osg::Vec3(2, 0, 0), osg::Vec3(0, 2, 0))); + debugGeometry[i]->setCullingActive(false); + debugCameras[i]->addChild(debugGeometry[i]); + osg::ref_ptr stateSet = debugGeometry[i]->getOrCreateStateSet(); + stateSet->setAttributeAndModes(debugProgram, osg::StateAttribute::ON); + osg::ref_ptr textureUniform = new osg::Uniform("texture", debugTextureUnit); + //textureUniform->setType(osg::Uniform::SAMPLER_2D); + stateSet->addUniform(textureUniform.get()); + } } } diff --git a/components/sceneutil/shadow.hpp b/components/sceneutil/shadow.hpp index 3c665bac7..ec7bbb8d2 100644 --- a/components/sceneutil/shadow.hpp +++ b/components/sceneutil/shadow.hpp @@ -1,6 +1,7 @@ #ifndef COMPONENTS_SCENEUTIL_SHADOW_H #define COMPONENTS_SCENEUTIL_SHADOW_H +#include #include #include @@ -10,14 +11,12 @@ namespace SceneUtil class MWShadow : public osgShadow::ViewDependentShadowMap { public: - static const int numberOfShadowMapsPerLight = 3; - static const bool enableShadows = true; - static const bool debugHud = true; + static void setupShadowSettings(osg::ref_ptr settings, int castsShadowMask); + + static void disableShadowsForStateSet(osg::ref_ptr stateSet); MWShadow(); - const static int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight; - virtual void cull(osgUtil::CullVisitor& cv); virtual Shader::ShaderManager::DefineMap getShadowDefines(); @@ -31,6 +30,12 @@ namespace SceneUtil osg::ref_ptr debugProgram; std::vector> debugGeometry; + + const int numberOfShadowMapsPerLight; + const bool enableShadows; + const bool debugHud; + + const int baseShadowTextureUnit; }; } diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 253883402..bd63f2bc6 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -466,3 +466,22 @@ companion x = 0.25 companion y = 0.0 companion w = 0.75 companion h = 0.375 + +[Shadows] +# Enable or disable shadows. +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 = 1 +# Enable the debug hud to see what the shadow map(s) contain. +enable debug hud = false +# Attempt to better use the shadow map by making them cover a smaller area. Especially helpful when looking downwards with a high viewing distance. The performance impact of this may be very large. +compute tight scene bounds = false +# How large to make the shadow map(s). Higher values increase GPU load, but can produce better-looking results. Power-of-two values may turn out to be faster on some GPU/driver combinations. +shadow map resolution = 1024 +# Allow actors to cast shadows. Potentially decreases performance. +actor shadows = false +# Allow the player to cast shadows. Potentially decreases performance. +player shadows = false +# Allow terrain to cast shadows. Potentially decreases performance. +terrain shadows = false +# Note: Right now, there is no setting allowing toggling of shadows for statics \ No newline at end of file