mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-19 11:11:33 +00:00
Use settings values for Shaders settings
This commit is contained in:
parent
f5ddf55cdc
commit
08902371b4
30 changed files with 234 additions and 146 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "sdlinit.hpp"
|
#include "sdlinit.hpp"
|
||||||
|
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
|
||||||
|
@ -144,10 +146,18 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
|
|
||||||
// Lighting
|
// Lighting
|
||||||
int lightingMethod = 1;
|
int lightingMethod = 1;
|
||||||
if (Settings::Manager::getString("lighting method", "Shaders") == "legacy")
|
switch (Settings::shaders().mLightingMethod)
|
||||||
lightingMethod = 0;
|
{
|
||||||
else if (Settings::Manager::getString("lighting method", "Shaders") == "shaders")
|
case SceneUtil::LightingMethod::FFP:
|
||||||
lightingMethod = 2;
|
lightingMethod = 0;
|
||||||
|
break;
|
||||||
|
case SceneUtil::LightingMethod::PerObjectUniform:
|
||||||
|
lightingMethod = 1;
|
||||||
|
break;
|
||||||
|
case SceneUtil::LightingMethod::SingleUBO:
|
||||||
|
lightingMethod = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
lightingMethodComboBox->setCurrentIndex(lightingMethod);
|
lightingMethodComboBox->setCurrentIndex(lightingMethod);
|
||||||
|
|
||||||
// Shadows
|
// Shadows
|
||||||
|
@ -246,10 +256,12 @@ void Launcher::GraphicsPage::saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lighting
|
// Lighting
|
||||||
static std::array<std::string, 3> lightingMethodMap = { "legacy", "shaders compatibility", "shaders" };
|
static constexpr std::array<SceneUtil::LightingMethod, 3> lightingMethodMap = {
|
||||||
const std::string& cLightingMethod = lightingMethodMap[lightingMethodComboBox->currentIndex()];
|
SceneUtil::LightingMethod::FFP,
|
||||||
if (cLightingMethod != Settings::Manager::getString("lighting method", "Shaders"))
|
SceneUtil::LightingMethod::PerObjectUniform,
|
||||||
Settings::Manager::setString("lighting method", "Shaders", cLightingMethod);
|
SceneUtil::LightingMethod::SingleUBO,
|
||||||
|
};
|
||||||
|
Settings::shaders().mLightingMethod.set(lightingMethodMap[lightingMethodComboBox->currentIndex()]);
|
||||||
|
|
||||||
// Shadows
|
// Shadows
|
||||||
int cShadowDist = shadowDistanceCheckBox->checkState() != Qt::Unchecked ? shadowDistanceSpinBox->value() : 0;
|
int cShadowDist = shadowDistanceCheckBox->checkState() != Qt::Unchecked ? shadowDistanceSpinBox->value() : 0;
|
||||||
|
|
|
@ -87,10 +87,10 @@ namespace CSVRender
|
||||||
|
|
||||||
mView->getCamera()->setGraphicsContext(window);
|
mView->getCamera()->setGraphicsContext(window);
|
||||||
|
|
||||||
SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager;
|
osg::ref_ptr<SceneUtil::LightManager> lightMgr = new SceneUtil::LightManager;
|
||||||
lightMgr->setStartLight(1);
|
lightMgr->setStartLight(1);
|
||||||
lightMgr->setLightingMask(Mask_Lighting);
|
lightMgr->setLightingMask(Mask_Lighting);
|
||||||
mRootNode = lightMgr;
|
mRootNode = std::move(lightMgr);
|
||||||
|
|
||||||
mView->getCamera()->setViewport(new osg::Viewport(0, 0, width(), height()));
|
mView->getCamera()->setViewport(new osg::Viewport(0, 0, width(), height()));
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ namespace
|
||||||
constexpr int min = 8;
|
constexpr int min = 8;
|
||||||
constexpr int max = 32;
|
constexpr int max = 32;
|
||||||
constexpr int increment = 8;
|
constexpr int increment = 8;
|
||||||
int maxLights = Settings::Manager::getInt("max lights", "Shaders");
|
const int maxLights = Settings::shaders().mMaxLights;
|
||||||
// show increments of 8 in dropdown
|
// show increments of 8 in dropdown
|
||||||
if (maxLights >= min && maxLights <= max && !(maxLights % increment))
|
if (maxLights >= min && maxLights <= max && !(maxLights % increment))
|
||||||
box->setIndexSelected((maxLights / increment) - 1);
|
box->setIndexSelected((maxLights / increment) - 1);
|
||||||
|
@ -559,7 +559,8 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(
|
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(
|
||||||
"#{OMWEngine:ChangeRequiresRestart}", { "#{Interface:OK}" }, true);
|
"#{OMWEngine:ChangeRequiresRestart}", { "#{Interface:OK}" }, true);
|
||||||
|
|
||||||
Settings::Manager::setString("lighting method", "Shaders", *_sender->getItemDataAt<std::string>(pos));
|
Settings::shaders().mLightingMethod.set(
|
||||||
|
Settings::parseLightingMethod(*_sender->getItemDataAt<std::string>(pos)));
|
||||||
apply();
|
apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,9 +631,7 @@ namespace MWGui
|
||||||
|
|
||||||
void SettingsWindow::onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos)
|
void SettingsWindow::onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos)
|
||||||
{
|
{
|
||||||
int count = 8 * (pos + 1);
|
Settings::shaders().mMaxLights.set(8 * (pos + 1));
|
||||||
|
|
||||||
Settings::Manager::setInt("max lights", "Shaders", count);
|
|
||||||
apply();
|
apply();
|
||||||
configureWidgets(mMainWidget, false);
|
configureWidgets(mMainWidget, false);
|
||||||
}
|
}
|
||||||
|
@ -653,8 +652,7 @@ namespace MWGui
|
||||||
Settings::shaders().mMaxLights.reset();
|
Settings::shaders().mMaxLights.reset();
|
||||||
Settings::shaders().mLightingMethod.reset();
|
Settings::shaders().mLightingMethod.reset();
|
||||||
|
|
||||||
const SceneUtil::LightingMethod lightingMethod
|
const SceneUtil::LightingMethod lightingMethod = Settings::shaders().mLightingMethod;
|
||||||
= SceneUtil::LightManager::getLightingMethodFromString(Settings::shaders().mLightingMethod);
|
|
||||||
const std::size_t lightIndex = mLightingMethodButton->findItemIndexWith(lightingMethodToStr(lightingMethod));
|
const std::size_t lightIndex = mLightingMethodButton->findItemIndexWith(lightingMethodToStr(lightingMethod));
|
||||||
mLightingMethodButton->setIndexSelected(lightIndex);
|
mLightingMethodButton->setIndexSelected(lightIndex);
|
||||||
updateMaxLightsComboBox(mMaxLights);
|
updateMaxLightsComboBox(mMaxLights);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <components/sceneutil/nodecallback.hpp>
|
#include <components/sceneutil/nodecallback.hpp>
|
||||||
#include <components/sceneutil/rtt.hpp>
|
#include <components/sceneutil/rtt.hpp>
|
||||||
#include <components/sceneutil/shadow.hpp>
|
#include <components/sceneutil/shadow.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/values.hpp>
|
||||||
#include <components/stereo/multiview.hpp>
|
#include <components/stereo/multiview.hpp>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
#include "../mwmechanics/weapontype.hpp"
|
#include "../mwmechanics/weapontype.hpp"
|
||||||
|
|
||||||
#include "npcanimation.hpp"
|
#include "npcanimation.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -154,7 +155,7 @@ namespace MWRender
|
||||||
public:
|
public:
|
||||||
CharacterPreviewRTTNode(uint32_t sizeX, uint32_t sizeY)
|
CharacterPreviewRTTNode(uint32_t sizeX, uint32_t sizeY)
|
||||||
: RTTNode(sizeX, sizeY, Settings::Manager::getInt("antialiasing", "Video"), false, 0,
|
: RTTNode(sizeX, sizeY, Settings::Manager::getInt("antialiasing", "Video"), false, 0,
|
||||||
StereoAwareness::Unaware_MultiViewShaders)
|
StereoAwareness::Unaware_MultiViewShaders, shouldAddMSAAIntermediateTarget())
|
||||||
, mAspectRatio(static_cast<float>(sizeX) / static_cast<float>(sizeY))
|
, mAspectRatio(static_cast<float>(sizeX) / static_cast<float>(sizeY))
|
||||||
{
|
{
|
||||||
if (SceneUtil::AutoDepth::isReversed())
|
if (SceneUtil::AutoDepth::isReversed())
|
||||||
|
@ -226,9 +227,13 @@ namespace MWRender
|
||||||
mRTTNode = new CharacterPreviewRTTNode(sizeX, sizeY);
|
mRTTNode = new CharacterPreviewRTTNode(sizeX, sizeY);
|
||||||
mRTTNode->setNodeMask(Mask_RenderToTexture);
|
mRTTNode->setNodeMask(Mask_RenderToTexture);
|
||||||
|
|
||||||
bool ffp = mResourceSystem->getSceneManager()->getLightingMethod() == SceneUtil::LightingMethod::FFP;
|
osg::ref_ptr<SceneUtil::LightManager> lightManager = new SceneUtil::LightManager(SceneUtil::LightSettings{
|
||||||
|
.mLightingMethod = mResourceSystem->getSceneManager()->getLightingMethod(),
|
||||||
osg::ref_ptr<SceneUtil::LightManager> lightManager = new SceneUtil::LightManager(ffp);
|
.mMaxLights = Settings::shaders().mMaxLights,
|
||||||
|
.mMaximumLightDistance = Settings::shaders().mMaximumLightDistance,
|
||||||
|
.mLightFadeStart = Settings::shaders().mLightFadeStart,
|
||||||
|
.mLightBoundsMultiplier = Settings::shaders().mLightBoundsMultiplier,
|
||||||
|
});
|
||||||
lightManager->setStartLight(1);
|
lightManager->setStartLight(1);
|
||||||
osg::ref_ptr<osg::StateSet> stateset = lightManager->getOrCreateStateSet();
|
osg::ref_ptr<osg::StateSet> stateset = lightManager->getOrCreateStateSet();
|
||||||
stateset->setDefine("FORCE_OPAQUE", "1", osg::StateAttribute::ON);
|
stateset->setDefine("FORCE_OPAQUE", "1", osg::StateAttribute::ON);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
|
#include "util.hpp"
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -679,7 +680,7 @@ namespace MWRender
|
||||||
|
|
||||||
LocalMapRenderToTexture::LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, float x, float y,
|
LocalMapRenderToTexture::LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, float x, float y,
|
||||||
const osg::Vec3d& upVector, float zmin, float zmax)
|
const osg::Vec3d& upVector, float zmin, float zmax)
|
||||||
: RTTNode(res, res, 0, false, 0, StereoAwareness::Unaware_MultiViewShaders)
|
: RTTNode(res, res, 0, false, 0, StereoAwareness::Unaware_MultiViewShaders, shouldAddMSAAIntermediateTarget())
|
||||||
, mSceneRoot(sceneRoot)
|
, mSceneRoot(sceneRoot)
|
||||||
, mActive(true)
|
, mActive(true)
|
||||||
{
|
{
|
||||||
|
|
|
@ -122,7 +122,6 @@ namespace MWRender
|
||||||
, mReload(false)
|
, mReload(false)
|
||||||
, mEnabled(false)
|
, mEnabled(false)
|
||||||
, mUsePostProcessing(Settings::postProcessing().mEnabled)
|
, mUsePostProcessing(Settings::postProcessing().mEnabled)
|
||||||
, mSoftParticles(false)
|
|
||||||
, mDisableDepthPasses(false)
|
, mDisableDepthPasses(false)
|
||||||
, mLastFrameNumber(0)
|
, mLastFrameNumber(0)
|
||||||
, mLastSimulationTime(0.f)
|
, mLastSimulationTime(0.f)
|
||||||
|
@ -135,8 +134,6 @@ namespace MWRender
|
||||||
, mPassLights(false)
|
, mPassLights(false)
|
||||||
, mPrevPassLights(false)
|
, mPrevPassLights(false)
|
||||||
{
|
{
|
||||||
mSoftParticles = Settings::Manager::getBool("soft particles", "Shaders");
|
|
||||||
|
|
||||||
osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
|
osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
|
||||||
osg::GLExtensions* ext = gc->getState()->get<osg::GLExtensions>();
|
osg::GLExtensions* ext = gc->getState()->get<osg::GLExtensions>();
|
||||||
|
|
||||||
|
@ -155,7 +152,7 @@ namespace MWRender
|
||||||
else
|
else
|
||||||
Log(Debug::Error) << "'glDisablei' unsupported, pass normals will not be available to shaders.";
|
Log(Debug::Error) << "'glDisablei' unsupported, pass normals will not be available to shaders.";
|
||||||
|
|
||||||
if (mSoftParticles)
|
if (Settings::shaders().mSoftParticles)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +169,8 @@ namespace MWRender
|
||||||
mUBO = ext->isUniformBufferObjectSupported && mGLSLVersion >= 330;
|
mUBO = ext->isUniformBufferObjectSupported && mGLSLVersion >= 330;
|
||||||
mStateUpdater = new fx::StateUpdater(mUBO);
|
mStateUpdater = new fx::StateUpdater(mUBO);
|
||||||
|
|
||||||
if (!Stereo::getStereo() && !SceneUtil::AutoDepth::isReversed() && !mSoftParticles && !mUsePostProcessing)
|
if (!Stereo::getStereo() && !SceneUtil::AutoDepth::isReversed() && !Settings::shaders().mSoftParticles
|
||||||
|
&& !mUsePostProcessing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
enable(mUsePostProcessing);
|
enable(mUsePostProcessing);
|
||||||
|
@ -239,7 +237,7 @@ namespace MWRender
|
||||||
const bool postPass = Settings::postProcessing().mTransparentPostpass;
|
const bool postPass = Settings::postProcessing().mTransparentPostpass;
|
||||||
mUsePostProcessing = usePostProcessing;
|
mUsePostProcessing = usePostProcessing;
|
||||||
|
|
||||||
mDisableDepthPasses = !mSoftParticles && !postPass;
|
mDisableDepthPasses = !Settings::shaders().mSoftParticles && !postPass;
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
mDisableDepthPasses = true;
|
mDisableDepthPasses = true;
|
||||||
|
@ -276,10 +274,10 @@ namespace MWRender
|
||||||
|
|
||||||
void PostProcessor::disable()
|
void PostProcessor::disable()
|
||||||
{
|
{
|
||||||
if (!mSoftParticles)
|
if (!Settings::shaders().mSoftParticles)
|
||||||
osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin")->setDrawCallback(nullptr);
|
osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin")->setDrawCallback(nullptr);
|
||||||
|
|
||||||
if (!SceneUtil::AutoDepth::isReversed() && !mSoftParticles)
|
if (!SceneUtil::AutoDepth::isReversed() && !Settings::shaders().mSoftParticles)
|
||||||
{
|
{
|
||||||
removeChild(mHUDCamera);
|
removeChild(mHUDCamera);
|
||||||
setCullCallback(nullptr);
|
setCullCallback(nullptr);
|
||||||
|
|
|
@ -175,8 +175,6 @@ namespace MWRender
|
||||||
|
|
||||||
bool isEnabled() const { return mUsePostProcessing && mEnabled; }
|
bool isEnabled() const { return mUsePostProcessing && mEnabled; }
|
||||||
|
|
||||||
bool softParticlesEnabled() const { return mSoftParticles; }
|
|
||||||
|
|
||||||
bool getHDR() const { return mHDR; }
|
bool getHDR() const { return mHDR; }
|
||||||
|
|
||||||
void disable();
|
void disable();
|
||||||
|
@ -247,7 +245,6 @@ namespace MWRender
|
||||||
bool mReload;
|
bool mReload;
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
bool mUsePostProcessing;
|
bool mUsePostProcessing;
|
||||||
bool mSoftParticles;
|
|
||||||
bool mDisableDepthPasses;
|
bool mDisableDepthPasses;
|
||||||
|
|
||||||
size_t mLastFrameNumber;
|
size_t mLastFrameNumber;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <components/sceneutil/depth.hpp>
|
#include <components/sceneutil/depth.hpp>
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
#include <components/sceneutil/util.hpp>
|
#include <components/sceneutil/util.hpp>
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
#include <components/shader/shadermanager.hpp>
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -112,7 +113,7 @@ namespace MWRender
|
||||||
mCamera->attach(osg::Camera::DEPTH_BUFFER, mDepthTexture);
|
mCamera->attach(osg::Camera::DEPTH_BUFFER, mDepthTexture);
|
||||||
mCamera->addChild(mSceneNode);
|
mCamera->addChild(mSceneNode);
|
||||||
mCamera->setSmallFeatureCullingPixelSize(
|
mCamera->setSmallFeatureCullingPixelSize(
|
||||||
Settings::Manager::getFloat("weather particle occlusion small feature culling pixel size", "Shaders"));
|
Settings::shaders().mWeatherParticleOcclusionSmallFeatureCullingPixelSize);
|
||||||
|
|
||||||
SceneUtil::setCameraClearDepth(mCamera);
|
SceneUtil::setCameraClearDepth(mCamera);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@
|
||||||
#include "screenshotmanager.hpp"
|
#include "screenshotmanager.hpp"
|
||||||
#include "sky.hpp"
|
#include "sky.hpp"
|
||||||
#include "terrainstorage.hpp"
|
#include "terrainstorage.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
#include "water.hpp"
|
#include "water.hpp"
|
||||||
|
|
||||||
|
@ -312,7 +313,6 @@ namespace MWRender
|
||||||
, mResourceSystem(resourceSystem)
|
, mResourceSystem(resourceSystem)
|
||||||
, mWorkQueue(workQueue)
|
, mWorkQueue(workQueue)
|
||||||
, mNavigator(navigator)
|
, mNavigator(navigator)
|
||||||
, mMinimumAmbientLuminance(0.f)
|
|
||||||
, mNightEyeFactor(0.f)
|
, mNightEyeFactor(0.f)
|
||||||
// TODO: Near clip should not need to be bounded like this, but too small values break OSG shadow calculations
|
// TODO: Near clip should not need to be bounded like this, but too small values break OSG shadow calculations
|
||||||
// CPU-side. See issue: #6072
|
// CPU-side. See issue: #6072
|
||||||
|
@ -325,46 +325,40 @@ namespace MWRender
|
||||||
, mGroundCoverStore(groundcoverStore)
|
, mGroundCoverStore(groundcoverStore)
|
||||||
{
|
{
|
||||||
bool reverseZ = SceneUtil::AutoDepth::isReversed();
|
bool reverseZ = SceneUtil::AutoDepth::isReversed();
|
||||||
auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(
|
const SceneUtil::LightingMethod lightingMethod = Settings::shaders().mLightingMethod;
|
||||||
Settings::Manager::getString("lighting method", "Shaders"));
|
|
||||||
|
|
||||||
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
|
resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem);
|
||||||
// Shadows and radial fog have problems with fixed-function mode.
|
// Shadows and radial fog have problems with fixed-function mode.
|
||||||
bool forceShaders = Settings::fog().mRadialFog || Settings::fog().mExponentialFog
|
bool forceShaders = Settings::fog().mRadialFog || Settings::fog().mExponentialFog
|
||||||
|| Settings::Manager::getBool("soft particles", "Shaders")
|
|| Settings::shaders().mSoftParticles || Settings::shaders().mForceShaders
|
||||||
|| Settings::Manager::getBool("force shaders", "Shaders")
|
|
||||||
|| Settings::Manager::getBool("enable shadows", "Shadows")
|
|| Settings::Manager::getBool("enable shadows", "Shadows")
|
||||||
|| lightingMethod != SceneUtil::LightingMethod::FFP || reverseZ || mSkyBlending || Stereo::getMultiview();
|
|| lightingMethod != SceneUtil::LightingMethod::FFP || reverseZ || mSkyBlending || Stereo::getMultiview();
|
||||||
resourceSystem->getSceneManager()->setForceShaders(forceShaders);
|
resourceSystem->getSceneManager()->setForceShaders(forceShaders);
|
||||||
|
|
||||||
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped
|
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped
|
||||||
resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders"));
|
resourceSystem->getSceneManager()->setClampLighting(Settings::shaders().mClampLighting);
|
||||||
resourceSystem->getSceneManager()->setAutoUseNormalMaps(
|
resourceSystem->getSceneManager()->setAutoUseNormalMaps(Settings::shaders().mAutoUseObjectNormalMaps);
|
||||||
Settings::Manager::getBool("auto use object normal maps", "Shaders"));
|
resourceSystem->getSceneManager()->setNormalMapPattern(Settings::shaders().mNormalMapPattern);
|
||||||
resourceSystem->getSceneManager()->setNormalMapPattern(
|
resourceSystem->getSceneManager()->setNormalHeightMapPattern(Settings::shaders().mNormalHeightMapPattern);
|
||||||
Settings::Manager::getString("normal map pattern", "Shaders"));
|
resourceSystem->getSceneManager()->setAutoUseSpecularMaps(Settings::shaders().mAutoUseObjectSpecularMaps);
|
||||||
resourceSystem->getSceneManager()->setNormalHeightMapPattern(
|
resourceSystem->getSceneManager()->setSpecularMapPattern(Settings::shaders().mSpecularMapPattern);
|
||||||
Settings::Manager::getString("normal height map pattern", "Shaders"));
|
|
||||||
resourceSystem->getSceneManager()->setAutoUseSpecularMaps(
|
|
||||||
Settings::Manager::getBool("auto use object specular maps", "Shaders"));
|
|
||||||
resourceSystem->getSceneManager()->setSpecularMapPattern(
|
|
||||||
Settings::Manager::getString("specular map pattern", "Shaders"));
|
|
||||||
resourceSystem->getSceneManager()->setApplyLightingToEnvMaps(
|
resourceSystem->getSceneManager()->setApplyLightingToEnvMaps(
|
||||||
Settings::Manager::getBool("apply lighting to environment maps", "Shaders"));
|
Settings::shaders().mApplyLightingToEnvironmentMaps);
|
||||||
resourceSystem->getSceneManager()->setConvertAlphaTestToAlphaToCoverage(
|
resourceSystem->getSceneManager()->setConvertAlphaTestToAlphaToCoverage(shouldAddMSAAIntermediateTarget());
|
||||||
Settings::Manager::getBool("antialias alpha test", "Shaders")
|
|
||||||
&& Settings::Manager::getInt("antialiasing", "Video") > 1);
|
|
||||||
resourceSystem->getSceneManager()->setAdjustCoverageForAlphaTest(
|
resourceSystem->getSceneManager()->setAdjustCoverageForAlphaTest(
|
||||||
Settings::Manager::getBool("adjust coverage for alpha test", "Shaders"));
|
Settings::shaders().mAdjustCoverageForAlphaTest);
|
||||||
|
|
||||||
// Let LightManager choose which backend to use based on our hint. For methods besides legacy lighting, this
|
// Let LightManager choose which backend to use based on our hint. For methods besides legacy lighting, this
|
||||||
// depends on support for various OpenGL extensions.
|
// depends on support for various OpenGL extensions.
|
||||||
osg::ref_ptr<SceneUtil::LightManager> sceneRoot
|
osg::ref_ptr<SceneUtil::LightManager> sceneRoot = new SceneUtil::LightManager(SceneUtil::LightSettings{
|
||||||
= new SceneUtil::LightManager(lightingMethod == SceneUtil::LightingMethod::FFP);
|
.mLightingMethod = lightingMethod,
|
||||||
|
.mMaxLights = Settings::shaders().mMaxLights,
|
||||||
|
.mMaximumLightDistance = Settings::shaders().mMaximumLightDistance,
|
||||||
|
.mLightFadeStart = Settings::shaders().mLightFadeStart,
|
||||||
|
.mLightBoundsMultiplier = Settings::shaders().mLightBoundsMultiplier,
|
||||||
|
});
|
||||||
resourceSystem->getSceneManager()->setLightingMethod(sceneRoot->getLightingMethod());
|
resourceSystem->getSceneManager()->setLightingMethod(sceneRoot->getLightingMethod());
|
||||||
resourceSystem->getSceneManager()->setSupportedLightingMethods(sceneRoot->getSupportedLightingMethods());
|
resourceSystem->getSceneManager()->setSupportedLightingMethods(sceneRoot->getSupportedLightingMethods());
|
||||||
mMinimumAmbientLuminance
|
|
||||||
= std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f);
|
|
||||||
|
|
||||||
sceneRoot->setLightingMask(Mask_Lighting);
|
sceneRoot->setLightingMask(Mask_Lighting);
|
||||||
mSceneRoot = sceneRoot;
|
mSceneRoot = sceneRoot;
|
||||||
|
@ -396,10 +390,9 @@ namespace MWRender
|
||||||
for (auto itr = shadowDefines.begin(); itr != shadowDefines.end(); itr++)
|
for (auto itr = shadowDefines.begin(); itr != shadowDefines.end(); itr++)
|
||||||
globalDefines[itr->first] = itr->second;
|
globalDefines[itr->first] = itr->second;
|
||||||
|
|
||||||
globalDefines["forcePPL"] = Settings::Manager::getBool("force per pixel lighting", "Shaders") ? "1" : "0";
|
globalDefines["forcePPL"] = Settings::shaders().mForcePerPixelLighting ? "1" : "0";
|
||||||
globalDefines["clamp"] = Settings::Manager::getBool("clamp lighting", "Shaders") ? "1" : "0";
|
globalDefines["clamp"] = Settings::shaders().mClampLighting ? "1" : "0";
|
||||||
globalDefines["preLightEnv"]
|
globalDefines["preLightEnv"] = Settings::shaders().mApplyLightingToEnvironmentMaps ? "1" : "0";
|
||||||
= Settings::Manager::getBool("apply lighting to environment maps", "Shaders") ? "1" : "0";
|
|
||||||
const bool exponentialFog = Settings::fog().mExponentialFog;
|
const bool exponentialFog = Settings::fog().mExponentialFog;
|
||||||
globalDefines["radialFog"] = (exponentialFog || Settings::fog().mRadialFog) ? "1" : "0";
|
globalDefines["radialFog"] = (exponentialFog || Settings::fog().mRadialFog) ? "1" : "0";
|
||||||
globalDefines["exponentialFog"] = exponentialFog ? "1" : "0";
|
globalDefines["exponentialFog"] = exponentialFog ? "1" : "0";
|
||||||
|
@ -445,11 +438,11 @@ namespace MWRender
|
||||||
|
|
||||||
mEffectManager = std::make_unique<EffectManager>(sceneRoot, mResourceSystem);
|
mEffectManager = std::make_unique<EffectManager>(sceneRoot, mResourceSystem);
|
||||||
|
|
||||||
const std::string& normalMapPattern = Settings::Manager::getString("normal map pattern", "Shaders");
|
const std::string& normalMapPattern = Settings::shaders().mNormalMapPattern;
|
||||||
const std::string& heightMapPattern = Settings::Manager::getString("normal height map pattern", "Shaders");
|
const std::string& heightMapPattern = Settings::shaders().mNormalHeightMapPattern;
|
||||||
const std::string& specularMapPattern = Settings::Manager::getString("terrain specular map pattern", "Shaders");
|
const std::string& specularMapPattern = Settings::shaders().mTerrainSpecularMapPattern;
|
||||||
const bool useTerrainNormalMaps = Settings::Manager::getBool("auto use terrain normal maps", "Shaders");
|
const bool useTerrainNormalMaps = Settings::shaders().mAutoUseTerrainNormalMaps;
|
||||||
const bool useTerrainSpecularMaps = Settings::Manager::getBool("auto use terrain specular maps", "Shaders");
|
const bool useTerrainSpecularMaps = Settings::shaders().mAutoUseTerrainSpecularMaps;
|
||||||
|
|
||||||
mTerrainStorage = std::make_unique<TerrainStorage>(mResourceSystem, normalMapPattern, heightMapPattern,
|
mTerrainStorage = std::make_unique<TerrainStorage>(mResourceSystem, normalMapPattern, heightMapPattern,
|
||||||
useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps);
|
useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps);
|
||||||
|
@ -472,8 +465,9 @@ namespace MWRender
|
||||||
resourceSystem->getSceneManager()->setOpaqueDepthTex(
|
resourceSystem->getSceneManager()->setOpaqueDepthTex(
|
||||||
mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 0),
|
mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 0),
|
||||||
mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 1));
|
mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 1));
|
||||||
resourceSystem->getSceneManager()->setSoftParticles(mPostProcessor->softParticlesEnabled());
|
resourceSystem->getSceneManager()->setSoftParticles(Settings::shaders().mSoftParticles);
|
||||||
resourceSystem->getSceneManager()->setSupportsNormalsRT(mPostProcessor->getSupportsNormalsRT());
|
resourceSystem->getSceneManager()->setSupportsNormalsRT(mPostProcessor->getSupportsNormalsRT());
|
||||||
|
resourceSystem->getSceneManager()->setWeatherParticleOcclusion(Settings::shaders().mWeatherParticleOcclusion);
|
||||||
|
|
||||||
// water goes after terrain for correct waterculling order
|
// water goes after terrain for correct waterculling order
|
||||||
mWater = std::make_unique<Water>(
|
mWater = std::make_unique<Water>(
|
||||||
|
@ -680,15 +674,16 @@ namespace MWRender
|
||||||
|
|
||||||
// we already work in linear RGB so no conversions are needed for the luminosity function
|
// we already work in linear RGB so no conversions are needed for the luminosity function
|
||||||
float relativeLuminance = pR * ambient.r() + pG * ambient.g() + pB * ambient.b();
|
float relativeLuminance = pR * ambient.r() + pG * ambient.g() + pB * ambient.b();
|
||||||
if (relativeLuminance < mMinimumAmbientLuminance)
|
const float minimumAmbientLuminance = Settings::shaders().mMinimumInteriorBrightness;
|
||||||
|
if (relativeLuminance < minimumAmbientLuminance)
|
||||||
{
|
{
|
||||||
// brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data
|
// brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data
|
||||||
// as least we can
|
// as least we can
|
||||||
if (ambient.r() == 0.f && ambient.g() == 0.f && ambient.b() == 0.f)
|
if (ambient.r() == 0.f && ambient.g() == 0.f && ambient.b() == 0.f)
|
||||||
ambient = osg::Vec4(
|
ambient = osg::Vec4(
|
||||||
mMinimumAmbientLuminance, mMinimumAmbientLuminance, mMinimumAmbientLuminance, ambient.a());
|
minimumAmbientLuminance, minimumAmbientLuminance, minimumAmbientLuminance, ambient.a());
|
||||||
else
|
else
|
||||||
ambient *= mMinimumAmbientLuminance / relativeLuminance;
|
ambient *= minimumAmbientLuminance / relativeLuminance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1408,8 +1403,6 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
else if (it->first == "Shaders" && it->second == "minimum interior brightness")
|
else if (it->first == "Shaders" && it->second == "minimum interior brightness")
|
||||||
{
|
{
|
||||||
mMinimumAmbientLuminance
|
|
||||||
= std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f);
|
|
||||||
if (MWMechanics::getPlayer().isInCell())
|
if (MWMechanics::getPlayer().isInCell())
|
||||||
configureAmbient(*MWMechanics::getPlayer().getCell()->getCell());
|
configureAmbient(*MWMechanics::getPlayer().getCell()->getCell());
|
||||||
}
|
}
|
||||||
|
@ -1418,13 +1411,15 @@ namespace MWRender
|
||||||
|| it->second == "light fade start" || it->second == "max lights"))
|
|| it->second == "light fade start" || it->second == "max lights"))
|
||||||
{
|
{
|
||||||
auto* lightManager = getLightRoot();
|
auto* lightManager = getLightRoot();
|
||||||
lightManager->processChangedSettings(changed);
|
|
||||||
|
lightManager->processChangedSettings(Settings::shaders().mLightBoundsMultiplier,
|
||||||
|
Settings::shaders().mMaximumLightDistance, Settings::shaders().mLightFadeStart);
|
||||||
|
|
||||||
if (it->second == "max lights" && !lightManager->usingFFP())
|
if (it->second == "max lights" && !lightManager->usingFFP())
|
||||||
{
|
{
|
||||||
mViewer->stopThreading();
|
mViewer->stopThreading();
|
||||||
|
|
||||||
lightManager->updateMaxLights();
|
lightManager->updateMaxLights(Settings::shaders().mMaxLights);
|
||||||
|
|
||||||
auto defines = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines();
|
auto defines = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines();
|
||||||
for (const auto& [name, key] : lightManager->getLightDefines())
|
for (const auto& [name, key] : lightManager->getLightDefines())
|
||||||
|
|
|
@ -342,7 +342,6 @@ namespace MWRender
|
||||||
osg::ref_ptr<PerViewUniformStateUpdater> mPerViewUniformStateUpdater;
|
osg::ref_ptr<PerViewUniformStateUpdater> mPerViewUniformStateUpdater;
|
||||||
|
|
||||||
osg::Vec4f mAmbientColor;
|
osg::Vec4f mAmbientColor;
|
||||||
float mMinimumAmbientLuminance;
|
|
||||||
float mNightEyeFactor;
|
float mNightEyeFactor;
|
||||||
|
|
||||||
float mNearClip;
|
float mNearClip;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "renderbin.hpp"
|
#include "renderbin.hpp"
|
||||||
#include "skyutil.hpp"
|
#include "skyutil.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -205,7 +206,8 @@ namespace
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkyRTT(osg::Vec2f size, osg::Group* earlyRenderBinRoot)
|
SkyRTT(osg::Vec2f size, osg::Group* earlyRenderBinRoot)
|
||||||
: RTTNode(static_cast<int>(size.x()), static_cast<int>(size.y()), 0, false, 1, StereoAwareness::Aware)
|
: RTTNode(static_cast<int>(size.x()), static_cast<int>(size.y()), 0, false, 1, StereoAwareness::Aware,
|
||||||
|
MWRender::shouldAddMSAAIntermediateTarget())
|
||||||
, mEarlyRenderBinRoot(earlyRenderBinRoot)
|
, mEarlyRenderBinRoot(earlyRenderBinRoot)
|
||||||
{
|
{
|
||||||
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
||||||
|
@ -292,7 +294,7 @@ namespace MWRender
|
||||||
mRootNode->addChild(mEarlyRenderBinRoot);
|
mRootNode->addChild(mEarlyRenderBinRoot);
|
||||||
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
||||||
|
|
||||||
mPrecipitationOcclusion = Settings::Manager::getBool("weather particle occlusion", "Shaders");
|
mPrecipitationOcclusion = Settings::shaders().mWeatherParticleOcclusion;
|
||||||
mPrecipitationOccluder = std::make_unique<PrecipitationOccluder>(skyroot, parentNode, rootNode, camera);
|
mPrecipitationOccluder = std::make_unique<PrecipitationOccluder>(skyroot, parentNode, rootNode, camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <components/resource/imagemanager.hpp>
|
#include <components/resource/imagemanager.hpp>
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
@ -67,4 +68,9 @@ namespace MWRender
|
||||||
node->setStateSet(stateset);
|
node->setStateSet(stateset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool shouldAddMSAAIntermediateTarget()
|
||||||
|
{
|
||||||
|
return Settings::shaders().mAntialiasAlphaTest && Settings::Manager::getInt("antialiasing", "Video") > 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <osg/NodeCallback>
|
#include <osg/NodeCallback>
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
|
@ -35,6 +36,8 @@ namespace MWRender
|
||||||
// no traverse()
|
// no traverse()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool shouldAddMSAAIntermediateTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,11 +35,14 @@
|
||||||
|
|
||||||
#include <components/fallback/fallback.hpp>
|
#include <components/fallback/fallback.hpp>
|
||||||
|
|
||||||
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
#include "renderbin.hpp"
|
#include "renderbin.hpp"
|
||||||
#include "ripples.hpp"
|
#include "ripples.hpp"
|
||||||
#include "ripplesimulation.hpp"
|
#include "ripplesimulation.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
#include "vismask.hpp"
|
#include "vismask.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -234,7 +237,7 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Refraction(uint32_t rttSize)
|
Refraction(uint32_t rttSize)
|
||||||
: RTTNode(rttSize, rttSize, 0, false, 1, StereoAwareness::Aware)
|
: RTTNode(rttSize, rttSize, 0, false, 1, StereoAwareness::Aware, shouldAddMSAAIntermediateTarget())
|
||||||
, mNodeMask(Refraction::sDefaultCullMask)
|
, mNodeMask(Refraction::sDefaultCullMask)
|
||||||
{
|
{
|
||||||
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
||||||
|
@ -315,7 +318,7 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Reflection(uint32_t rttSize, bool isInterior)
|
Reflection(uint32_t rttSize, bool isInterior)
|
||||||
: RTTNode(rttSize, rttSize, 0, false, 0, StereoAwareness::Aware)
|
: RTTNode(rttSize, rttSize, 0, false, 0, StereoAwareness::Aware, shouldAddMSAAIntermediateTarget())
|
||||||
{
|
{
|
||||||
setInterior(isInterior);
|
setInterior(isInterior);
|
||||||
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8);
|
||||||
|
|
|
@ -107,7 +107,7 @@ add_component_dir (sceneutil
|
||||||
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
|
clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller
|
||||||
lightmanager lightutil positionattitudetransform workqueue pathgridutil waterutil writescene serialize optimizer
|
lightmanager lightutil positionattitudetransform workqueue pathgridutil waterutil writescene serialize optimizer
|
||||||
detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller rtt
|
detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller rtt
|
||||||
screencapture depth color riggeometryosgaextension extradata unrefqueue lightcommon
|
screencapture depth color riggeometryosgaextension extradata unrefqueue lightcommon lightingmethod
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (nif
|
add_component_dir (nif
|
||||||
|
|
|
@ -1118,10 +1118,10 @@ namespace Resource
|
||||||
stats->setAttribute(frameNumber, "Node", mCache->getCacheSize());
|
stats->setAttribute(frameNumber, "Node", mCache->getCacheSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader::ShaderVisitor* SceneManager::createShaderVisitor(const std::string& shaderPrefix)
|
osg::ref_ptr<Shader::ShaderVisitor> SceneManager::createShaderVisitor(const std::string& shaderPrefix)
|
||||||
{
|
{
|
||||||
Shader::ShaderVisitor* shaderVisitor
|
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(
|
||||||
= new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix);
|
new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix));
|
||||||
shaderVisitor->setForceShaders(mForceShaders);
|
shaderVisitor->setForceShaders(mForceShaders);
|
||||||
shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps);
|
shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps);
|
||||||
shaderVisitor->setNormalMapPattern(mNormalMapPattern);
|
shaderVisitor->setNormalMapPattern(mNormalMapPattern);
|
||||||
|
@ -1132,6 +1132,7 @@ namespace Resource
|
||||||
shaderVisitor->setConvertAlphaTestToAlphaToCoverage(mConvertAlphaTestToAlphaToCoverage);
|
shaderVisitor->setConvertAlphaTestToAlphaToCoverage(mConvertAlphaTestToAlphaToCoverage);
|
||||||
shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest);
|
shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest);
|
||||||
shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT);
|
shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT);
|
||||||
|
shaderVisitor->setWeatherParticleOcclusion(mWeatherParticleOcclusion);
|
||||||
return shaderVisitor;
|
return shaderVisitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,8 +227,10 @@ namespace Resource
|
||||||
void setSoftParticles(bool enabled) { mSoftParticles = enabled; }
|
void setSoftParticles(bool enabled) { mSoftParticles = enabled; }
|
||||||
bool getSoftParticles() const { return mSoftParticles; }
|
bool getSoftParticles() const { return mSoftParticles; }
|
||||||
|
|
||||||
|
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects");
|
osg::ref_ptr<Shader::ShaderVisitor> createShaderVisitor(const std::string& shaderPrefix = "objects");
|
||||||
osg::ref_ptr<osg::Node> loadErrorMarker();
|
osg::ref_ptr<osg::Node> loadErrorMarker();
|
||||||
osg::ref_ptr<osg::Node> cloneErrorMarker();
|
osg::ref_ptr<osg::Node> cloneErrorMarker();
|
||||||
|
|
||||||
|
@ -248,6 +250,7 @@ namespace Resource
|
||||||
bool mSupportsNormalsRT;
|
bool mSupportsNormalsRT;
|
||||||
std::array<osg::ref_ptr<osg::Texture>, 2> mOpaqueDepthTex;
|
std::array<osg::ref_ptr<osg::Texture>, 2> mOpaqueDepthTex;
|
||||||
bool mSoftParticles = false;
|
bool mSoftParticles = false;
|
||||||
|
bool mWeatherParticleOcclusion = false;
|
||||||
|
|
||||||
osg::ref_ptr<Resource::SharedStateManager> mSharedStateManager;
|
osg::ref_ptr<Resource::SharedStateManager> mSharedStateManager;
|
||||||
mutable std::mutex mSharedStateMutex;
|
mutable std::mutex mSharedStateMutex;
|
||||||
|
|
14
components/sceneutil/lightingmethod.hpp
Normal file
14
components/sceneutil/lightingmethod.hpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_SCENEUTIL_LIGHTINGMETHOD_H
|
||||||
|
#define OPENMW_COMPONENTS_SCENEUTIL_LIGHTINGMETHOD_H
|
||||||
|
|
||||||
|
namespace SceneUtil
|
||||||
|
{
|
||||||
|
enum class LightingMethod
|
||||||
|
{
|
||||||
|
FFP,
|
||||||
|
PerObjectUniform,
|
||||||
|
SingleUBO,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr int maxLightsLowerLimit = 2;
|
|
||||||
constexpr int maxLightsUpperLimit = 64;
|
|
||||||
constexpr int ffpMaxLights = 8;
|
constexpr int ffpMaxLights = 8;
|
||||||
|
|
||||||
bool sortLights(const SceneUtil::LightManager::LightSourceViewBound* left,
|
bool sortLights(const SceneUtil::LightManager::LightSourceViewBound* left,
|
||||||
|
@ -817,7 +815,7 @@ namespace SceneUtil
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
LightManager::LightManager(bool ffp)
|
LightManager::LightManager(const LightSettings& settings)
|
||||||
: mStartLight(0)
|
: mStartLight(0)
|
||||||
, mLightingMask(~0u)
|
, mLightingMask(~0u)
|
||||||
, mSun(nullptr)
|
, mSun(nullptr)
|
||||||
|
@ -835,18 +833,15 @@ namespace SceneUtil
|
||||||
|
|
||||||
setUpdateCallback(new LightManagerUpdateCallback);
|
setUpdateCallback(new LightManagerUpdateCallback);
|
||||||
|
|
||||||
if (ffp)
|
if (settings.mLightingMethod == LightingMethod::FFP)
|
||||||
{
|
{
|
||||||
initFFP(ffpMaxLights);
|
initFFP(ffpMaxLights);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& lightingMethodString = Settings::Manager::getString("lighting method", "Shaders");
|
|
||||||
auto lightingMethod = LightManager::getLightingMethodFromString(lightingMethodString);
|
|
||||||
|
|
||||||
static bool hasLoggedWarnings = false;
|
static bool hasLoggedWarnings = false;
|
||||||
|
|
||||||
if (lightingMethod == LightingMethod::SingleUBO && !hasLoggedWarnings)
|
if (settings.mLightingMethod == LightingMethod::SingleUBO && !hasLoggedWarnings)
|
||||||
{
|
{
|
||||||
if (!supportsUBO)
|
if (!supportsUBO)
|
||||||
Log(Debug::Warning)
|
Log(Debug::Warning)
|
||||||
|
@ -857,15 +852,12 @@ namespace SceneUtil
|
||||||
hasLoggedWarnings = true;
|
hasLoggedWarnings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int targetLights
|
if (!supportsUBO || !supportsGPU4 || settings.mLightingMethod == LightingMethod::PerObjectUniform)
|
||||||
= std::clamp(Settings::Manager::getInt("max lights", "Shaders"), maxLightsLowerLimit, maxLightsUpperLimit);
|
initPerObjectUniform(settings.mMaxLights);
|
||||||
|
|
||||||
if (!supportsUBO || !supportsGPU4 || lightingMethod == LightingMethod::PerObjectUniform)
|
|
||||||
initPerObjectUniform(targetLights);
|
|
||||||
else
|
else
|
||||||
initSingleUBO(targetLights);
|
initSingleUBO(settings.mMaxLights);
|
||||||
|
|
||||||
updateSettings();
|
updateSettings(settings.mLightBoundsMultiplier, settings.mMaximumLightDistance, settings.mLightFadeStart);
|
||||||
|
|
||||||
getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0));
|
getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0));
|
||||||
|
|
||||||
|
@ -931,18 +923,18 @@ namespace SceneUtil
|
||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
void LightManager::processChangedSettings(
|
||||||
|
float lightBoundsMultiplier, float maximumLightDistance, float lightFadeStart)
|
||||||
{
|
{
|
||||||
updateSettings();
|
updateSettings(lightBoundsMultiplier, maximumLightDistance, lightFadeStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::updateMaxLights()
|
void LightManager::updateMaxLights(int maxLights)
|
||||||
{
|
{
|
||||||
if (usingFFP())
|
if (usingFFP())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setMaxLights(
|
setMaxLights(maxLights);
|
||||||
std::clamp(Settings::Manager::getInt("max lights", "Shaders"), maxLightsLowerLimit, maxLightsUpperLimit));
|
|
||||||
|
|
||||||
if (getLightingMethod() == LightingMethod::PerObjectUniform)
|
if (getLightingMethod() == LightingMethod::PerObjectUniform)
|
||||||
{
|
{
|
||||||
|
@ -954,20 +946,15 @@ namespace SceneUtil
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::updateSettings()
|
void LightManager::updateSettings(float lightBoundsMultiplier, float maximumLightDistance, float lightFadeStart)
|
||||||
{
|
{
|
||||||
if (getLightingMethod() == LightingMethod::FFP)
|
if (getLightingMethod() == LightingMethod::FFP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mPointLightRadiusMultiplier
|
mPointLightRadiusMultiplier = lightBoundsMultiplier;
|
||||||
= std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 5.f);
|
mPointLightFadeEnd = maximumLightDistance;
|
||||||
|
|
||||||
mPointLightFadeEnd = std::max(0.f, Settings::Manager::getFloat("maximum light distance", "Shaders"));
|
|
||||||
if (mPointLightFadeEnd > 0)
|
if (mPointLightFadeEnd > 0)
|
||||||
{
|
mPointLightFadeStart = mPointLightFadeEnd * lightFadeStart;
|
||||||
mPointLightFadeStart = std::clamp(Settings::Manager::getFloat("light fade start", "Shaders"), 0.f, 1.f);
|
|
||||||
mPointLightFadeStart = mPointLightFadeEnd * mPointLightFadeStart;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightManager::initFFP(int targetLights)
|
void LightManager::initFFP(int targetLights)
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
#include <osg/observer_ptr>
|
#include <osg/observer_ptr>
|
||||||
|
|
||||||
#include <components/sceneutil/nodecallback.hpp>
|
#include <components/sceneutil/nodecallback.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
#include "lightingmethod.hpp"
|
||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
@ -82,13 +83,6 @@ namespace SceneUtil
|
||||||
std::array<osg::ref_ptr<osg::Uniform>, 2> mUniformCount;
|
std::array<osg::ref_ptr<osg::Uniform>, 2> mUniformCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class LightingMethod
|
|
||||||
{
|
|
||||||
FFP,
|
|
||||||
PerObjectUniform,
|
|
||||||
SingleUBO,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// LightSource managed by a LightManager.
|
/// LightSource managed by a LightManager.
|
||||||
/// @par Typically used for point lights. Spot lights are not supported yet. Directional lights affect the whole
|
/// @par Typically used for point lights. Spot lights are not supported yet. Directional lights affect the whole
|
||||||
/// scene
|
/// scene
|
||||||
|
@ -186,6 +180,15 @@ namespace SceneUtil
|
||||||
osg::ref_ptr<LightBuffer> mTemplate;
|
osg::ref_ptr<LightBuffer> mTemplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LightSettings
|
||||||
|
{
|
||||||
|
LightingMethod mLightingMethod = LightingMethod::FFP;
|
||||||
|
int mMaxLights = 0;
|
||||||
|
float mMaximumLightDistance = 0;
|
||||||
|
float mLightFadeStart = 0;
|
||||||
|
float mLightBoundsMultiplier = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Decorator node implementing the rendering of any number of LightSources that can be anywhere in the
|
/// @brief Decorator node implementing the rendering of any number of LightSources that can be anywhere in the
|
||||||
/// subgraph.
|
/// subgraph.
|
||||||
class LightManager : public osg::Group
|
class LightManager : public osg::Group
|
||||||
|
@ -212,7 +215,7 @@ namespace SceneUtil
|
||||||
|
|
||||||
META_Node(SceneUtil, LightManager)
|
META_Node(SceneUtil, LightManager)
|
||||||
|
|
||||||
LightManager(bool ffp = true);
|
explicit LightManager(const LightSettings& settings = LightSettings{});
|
||||||
|
|
||||||
LightManager(const LightManager& copy, const osg::CopyOp& copyop);
|
LightManager(const LightManager& copy, const osg::CopyOp& copyop);
|
||||||
|
|
||||||
|
@ -264,10 +267,10 @@ namespace SceneUtil
|
||||||
|
|
||||||
std::map<std::string, std::string> getLightDefines() const;
|
std::map<std::string, std::string> getLightDefines() const;
|
||||||
|
|
||||||
void processChangedSettings(const Settings::CategorySettingVector& changed);
|
void processChangedSettings(float lightBoundsMultiplier, float maximumLightDistance, float lightFadeStart);
|
||||||
|
|
||||||
/// Not thread safe, it is the responsibility of the caller to stop/start threading on the viewer
|
/// Not thread safe, it is the responsibility of the caller to stop/start threading on the viewer
|
||||||
void updateMaxLights();
|
void updateMaxLights(int maxLights);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Uniform> generateLightBufferUniform(const osg::Matrixf& sun);
|
osg::ref_ptr<osg::Uniform> generateLightBufferUniform(const osg::Matrixf& sun);
|
||||||
|
|
||||||
|
@ -281,7 +284,7 @@ namespace SceneUtil
|
||||||
void initPerObjectUniform(int targetLights);
|
void initPerObjectUniform(int targetLights);
|
||||||
void initSingleUBO(int targetLights);
|
void initSingleUBO(int targetLights);
|
||||||
|
|
||||||
void updateSettings();
|
void updateSettings(float lightBoundsMultiplier, float maximumLightDistance, float lightFadeStart);
|
||||||
|
|
||||||
void setLightingMethod(LightingMethod method);
|
void setLightingMethod(LightingMethod method);
|
||||||
void setMaxLights(int value);
|
void setMaxLights(int value);
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SceneUtil
|
||||||
};
|
};
|
||||||
|
|
||||||
RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, uint32_t samples, bool generateMipmaps,
|
RTTNode::RTTNode(uint32_t textureWidth, uint32_t textureHeight, uint32_t samples, bool generateMipmaps,
|
||||||
int renderOrderNum, StereoAwareness stereoAwareness)
|
int renderOrderNum, StereoAwareness stereoAwareness, bool addMSAAIntermediateTarget)
|
||||||
: mTextureWidth(textureWidth)
|
: mTextureWidth(textureWidth)
|
||||||
, mTextureHeight(textureHeight)
|
, mTextureHeight(textureHeight)
|
||||||
, mSamples(samples)
|
, mSamples(samples)
|
||||||
|
@ -29,6 +29,7 @@ namespace SceneUtil
|
||||||
, mDepthBufferInternalFormat(SceneUtil::AutoDepth::depthInternalFormat())
|
, mDepthBufferInternalFormat(SceneUtil::AutoDepth::depthInternalFormat())
|
||||||
, mRenderOrderNum(renderOrderNum)
|
, mRenderOrderNum(renderOrderNum)
|
||||||
, mStereoAwareness(stereoAwareness)
|
, mStereoAwareness(stereoAwareness)
|
||||||
|
, mAddMSAAIntermediateTarget(addMSAAIntermediateTarget)
|
||||||
{
|
{
|
||||||
addCullCallback(new CullCallback);
|
addCullCallback(new CullCallback);
|
||||||
setCullingActive(false);
|
setCullingActive(false);
|
||||||
|
@ -206,7 +207,8 @@ namespace SceneUtil
|
||||||
camera->attach(osg::Camera::COLOR_BUFFER, vdd->mColorTexture, 0,
|
camera->attach(osg::Camera::COLOR_BUFFER, vdd->mColorTexture, 0,
|
||||||
Stereo::osgFaceControlledByMultiviewShader(), mGenerateMipmaps, mSamples);
|
Stereo::osgFaceControlledByMultiviewShader(), mGenerateMipmaps, mSamples);
|
||||||
SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(camera, osg::Camera::COLOR_BUFFER,
|
SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(camera, osg::Camera::COLOR_BUFFER,
|
||||||
vdd->mColorTexture, 0, Stereo::osgFaceControlledByMultiviewShader(), mGenerateMipmaps);
|
vdd->mColorTexture, 0, Stereo::osgFaceControlledByMultiviewShader(), mGenerateMipmaps,
|
||||||
|
mAddMSAAIntermediateTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0)
|
if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0)
|
||||||
|
@ -234,8 +236,8 @@ namespace SceneUtil
|
||||||
{
|
{
|
||||||
vdd->mColorTexture = createTexture(mColorBufferInternalFormat);
|
vdd->mColorTexture = createTexture(mColorBufferInternalFormat);
|
||||||
camera->attach(osg::Camera::COLOR_BUFFER, vdd->mColorTexture, 0, 0, mGenerateMipmaps, mSamples);
|
camera->attach(osg::Camera::COLOR_BUFFER, vdd->mColorTexture, 0, 0, mGenerateMipmaps, mSamples);
|
||||||
SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(
|
SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(camera, osg::Camera::COLOR_BUFFER,
|
||||||
camera, osg::Camera::COLOR_BUFFER, vdd->mColorTexture, 0, 0, mGenerateMipmaps);
|
vdd->mColorTexture, 0, 0, mGenerateMipmaps, mAddMSAAIntermediateTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0)
|
if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0)
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace SceneUtil
|
||||||
};
|
};
|
||||||
|
|
||||||
RTTNode(uint32_t textureWidth, uint32_t textureHeight, uint32_t samples, bool generateMipmaps,
|
RTTNode(uint32_t textureWidth, uint32_t textureHeight, uint32_t samples, bool generateMipmaps,
|
||||||
int renderOrderNum, StereoAwareness stereoAwareness);
|
int renderOrderNum, StereoAwareness stereoAwareness, bool addMSAAIntermediateTarget);
|
||||||
~RTTNode();
|
~RTTNode();
|
||||||
|
|
||||||
osg::Texture* getColorTexture(osgUtil::CullVisitor* cv);
|
osg::Texture* getColorTexture(osgUtil::CullVisitor* cv);
|
||||||
|
@ -110,6 +110,7 @@ namespace SceneUtil
|
||||||
GLint mDepthBufferInternalFormat;
|
GLint mDepthBufferInternalFormat;
|
||||||
int mRenderOrderNum;
|
int mRenderOrderNum;
|
||||||
StereoAwareness mStereoAwareness;
|
StereoAwareness mStereoAwareness;
|
||||||
|
bool mAddMSAAIntermediateTarget;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -239,13 +239,12 @@ namespace SceneUtil
|
||||||
return glowUpdater;
|
return glowUpdater;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer,
|
void attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer,
|
||||||
osg::Texture* texture, unsigned int level, unsigned int face, bool mipMapGeneration)
|
osg::Texture* texture, unsigned int level, unsigned int face, bool mipMapGeneration,
|
||||||
|
bool addMSAAIntermediateTarget)
|
||||||
{
|
{
|
||||||
unsigned int samples = 0;
|
unsigned int samples = 0;
|
||||||
unsigned int colourSamples = 0;
|
unsigned int colourSamples = 0;
|
||||||
bool addMSAAIntermediateTarget = Settings::Manager::getBool("antialias alpha test", "Shaders")
|
|
||||||
&& Settings::Manager::getInt("antialiasing", "Video") > 1;
|
|
||||||
if (addMSAAIntermediateTarget)
|
if (addMSAAIntermediateTarget)
|
||||||
{
|
{
|
||||||
// Alpha-to-coverage requires a multisampled framebuffer.
|
// Alpha-to-coverage requires a multisampled framebuffer.
|
||||||
|
@ -255,7 +254,6 @@ namespace SceneUtil
|
||||||
colourSamples = 1;
|
colourSamples = 1;
|
||||||
}
|
}
|
||||||
camera->attach(buffer, texture, level, face, mipMapGeneration, samples, colourSamples);
|
camera->attach(buffer, texture, level, face, mipMapGeneration, samples, colourSamples);
|
||||||
return addMSAAIntermediateTarget;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationSequence::OperationSequence(bool keep)
|
OperationSequence::OperationSequence(bool keep)
|
||||||
|
|
|
@ -96,8 +96,9 @@ namespace SceneUtil
|
||||||
const osg::Vec4f& glowColor, float glowDuration = -1);
|
const osg::Vec4f& glowColor, float glowDuration = -1);
|
||||||
|
|
||||||
// Alpha-to-coverage requires a multisampled framebuffer, so we need to set that up for RTTs
|
// Alpha-to-coverage requires a multisampled framebuffer, so we need to set that up for RTTs
|
||||||
bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer,
|
void attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::Camera::BufferComponent buffer,
|
||||||
osg::Texture* texture, unsigned int level = 0, unsigned int face = 0, bool mipMapGeneration = false);
|
osg::Texture* texture, unsigned int level, unsigned int face, bool mipMapGeneration,
|
||||||
|
bool addMSAAIntermediateTarget);
|
||||||
|
|
||||||
class OperationSequence : public osg::Operation
|
class OperationSequence : public osg::Operation
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
|
#ifndef OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
|
||||||
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
|
#define OPENMW_COMPONENTS_SETTINGS_CATEGORIES_SHADERS_H
|
||||||
|
|
||||||
|
#include "components/sceneutil/lightingmethod.hpp"
|
||||||
#include "components/settings/sanitizerimpl.hpp"
|
#include "components/settings/sanitizerimpl.hpp"
|
||||||
#include "components/settings/settingvalue.hpp"
|
#include "components/settings/settingvalue.hpp"
|
||||||
|
|
||||||
|
@ -30,11 +31,11 @@ namespace Settings
|
||||||
SettingValue<std::string> mSpecularMapPattern{ mIndex, "Shaders", "specular map pattern" };
|
SettingValue<std::string> mSpecularMapPattern{ mIndex, "Shaders", "specular map pattern" };
|
||||||
SettingValue<std::string> mTerrainSpecularMapPattern{ mIndex, "Shaders", "terrain specular map pattern" };
|
SettingValue<std::string> mTerrainSpecularMapPattern{ mIndex, "Shaders", "terrain specular map pattern" };
|
||||||
SettingValue<bool> mApplyLightingToEnvironmentMaps{ mIndex, "Shaders", "apply lighting to environment maps" };
|
SettingValue<bool> mApplyLightingToEnvironmentMaps{ mIndex, "Shaders", "apply lighting to environment maps" };
|
||||||
SettingValue<std::string> mLightingMethod{ mIndex, "Shaders", "lighting method",
|
SettingValue<SceneUtil::LightingMethod> mLightingMethod{ mIndex, "Shaders", "lighting method" };
|
||||||
makeEnumSanitizerString({ "legacy", "shaders compatibility", "shaders" }) };
|
|
||||||
SettingValue<float> mLightBoundsMultiplier{ mIndex, "Shaders", "light bounds multiplier",
|
SettingValue<float> mLightBoundsMultiplier{ mIndex, "Shaders", "light bounds multiplier",
|
||||||
makeClampSanitizerFloat(0, 5) };
|
makeClampSanitizerFloat(0, 5) };
|
||||||
SettingValue<float> mMaximumLightDistance{ mIndex, "Shaders", "maximum light distance" };
|
SettingValue<float> mMaximumLightDistance{ mIndex, "Shaders", "maximum light distance",
|
||||||
|
makeMaxSanitizerFloat(0) };
|
||||||
SettingValue<float> mLightFadeStart{ mIndex, "Shaders", "light fade start", makeClampSanitizerFloat(0, 1) };
|
SettingValue<float> mLightFadeStart{ mIndex, "Shaders", "light fade start", makeClampSanitizerFloat(0, 1) };
|
||||||
SettingValue<int> mMaxLights{ mIndex, "Shaders", "max lights", makeClampSanitizerInt(2, 64) };
|
SettingValue<int> mMaxLights{ mIndex, "Shaders", "max lights", makeClampSanitizerInt(2, 64) };
|
||||||
SettingValue<float> mMinimumInteriorBrightness{ mIndex, "Shaders", "minimum interior brightness",
|
SettingValue<float> mMinimumInteriorBrightness{ mIndex, "Shaders", "minimum interior brightness",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
#include <components/misc/strings/conversion.hpp>
|
#include <components/misc/strings/conversion.hpp>
|
||||||
|
@ -87,6 +88,21 @@ namespace Settings
|
||||||
stream << value;
|
stream << value;
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string toString(SceneUtil::LightingMethod value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SceneUtil::LightingMethod::FFP:
|
||||||
|
return "legacy";
|
||||||
|
case SceneUtil::LightingMethod::PerObjectUniform:
|
||||||
|
return "shaders compatibility";
|
||||||
|
case SceneUtil::LightingMethod::SingleUBO:
|
||||||
|
return "shaders";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::invalid_argument("Invalid LightingMethod value: " + std::to_string(static_cast<int>(value)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
|
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
|
||||||
|
@ -459,6 +475,11 @@ namespace Settings
|
||||||
setString(setting, category, value.print());
|
setString(setting, category, value.print());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::set(std::string_view setting, std::string_view category, SceneUtil::LightingMethod value)
|
||||||
|
{
|
||||||
|
setString(setting, category, toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::recordInit(std::string_view setting, std::string_view category)
|
void Manager::recordInit(std::string_view setting, std::string_view category)
|
||||||
{
|
{
|
||||||
sInitialized.emplace(category, setting);
|
sInitialized.emplace(category, setting);
|
||||||
|
@ -491,4 +512,18 @@ namespace Settings
|
||||||
|
|
||||||
throw std::invalid_argument("Invalid navigation mesh rendering mode: " + std::string(value));
|
throw std::invalid_argument("Invalid navigation mesh rendering mode: " + std::string(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneUtil::LightingMethod parseLightingMethod(std::string_view value)
|
||||||
|
{
|
||||||
|
if (value == "legacy")
|
||||||
|
return SceneUtil::LightingMethod::FFP;
|
||||||
|
if (value == "shaders compatibility")
|
||||||
|
return SceneUtil::LightingMethod::PerObjectUniform;
|
||||||
|
if (value == "shaders")
|
||||||
|
return SceneUtil::LightingMethod::SingleUBO;
|
||||||
|
|
||||||
|
constexpr const char* fallback = "shaders compatibility";
|
||||||
|
Log(Debug::Warning) << "Unknown lighting method '" << value << "', returning fallback '" << fallback << "'";
|
||||||
|
return SceneUtil::LightingMethod::PerObjectUniform;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include "gyroscopeaxis.hpp"
|
#include "gyroscopeaxis.hpp"
|
||||||
#include "navmeshrendermode.hpp"
|
#include "navmeshrendermode.hpp"
|
||||||
|
|
||||||
#include "components/detournavigator/collisionshapetype.hpp"
|
#include <components/detournavigator/collisionshapetype.hpp>
|
||||||
|
#include <components/sceneutil/lightingmethod.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -110,6 +111,7 @@ namespace Settings
|
||||||
static void set(std::string_view setting, std::string_view category, DetourNavigator::CollisionShapeType value);
|
static void set(std::string_view setting, std::string_view category, DetourNavigator::CollisionShapeType value);
|
||||||
static void set(std::string_view setting, std::string_view category, const std::vector<std::string>& value);
|
static void set(std::string_view setting, std::string_view category, const std::vector<std::string>& value);
|
||||||
static void set(std::string_view setting, std::string_view category, const MyGUI::Colour& value);
|
static void set(std::string_view setting, std::string_view category, const MyGUI::Colour& value);
|
||||||
|
static void set(std::string_view setting, std::string_view category, SceneUtil::LightingMethod value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::set<std::pair<std::string_view, std::string_view>> sInitialized;
|
static std::set<std::pair<std::string_view, std::string_view>> sInitialized;
|
||||||
|
@ -215,6 +217,15 @@ namespace Settings
|
||||||
{
|
{
|
||||||
return parseNavMeshRenderMode(getString(setting, category));
|
return parseNavMeshRenderMode(getString(setting, category));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneUtil::LightingMethod parseLightingMethod(std::string_view value);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline SceneUtil::LightingMethod Manager::getImpl<SceneUtil::LightingMethod>(
|
||||||
|
std::string_view setting, std::string_view category)
|
||||||
|
{
|
||||||
|
return parseLightingMethod(getString(setting, category));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMPONENTS_SETTINGS_H
|
#endif // COMPONENTS_SETTINGS_H
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace Settings
|
||||||
MyGuiColour,
|
MyGuiColour,
|
||||||
GyroscopeAxis,
|
GyroscopeAxis,
|
||||||
NavMeshRenderMode,
|
NavMeshRenderMode,
|
||||||
|
LightingMethod,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -147,6 +148,12 @@ namespace Settings
|
||||||
return SettingValueType::NavMeshRenderMode;
|
return SettingValueType::NavMeshRenderMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline constexpr SettingValueType getSettingValueType<SceneUtil::LightingMethod>()
|
||||||
|
{
|
||||||
|
return SettingValueType::LightingMethod;
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr std::string_view getSettingValueTypeName(SettingValueType type)
|
inline constexpr std::string_view getSettingValueTypeName(SettingValueType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -185,6 +192,8 @@ namespace Settings
|
||||||
return "gyroscope axis";
|
return "gyroscope axis";
|
||||||
case SettingValueType::NavMeshRenderMode:
|
case SettingValueType::NavMeshRenderMode:
|
||||||
return "navmesh render mode";
|
return "navmesh render mode";
|
||||||
|
case SettingValueType::LightingMethod:
|
||||||
|
return "lighting method";
|
||||||
}
|
}
|
||||||
return "unsupported";
|
return "unsupported";
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,8 +680,7 @@ namespace Shader
|
||||||
|
|
||||||
bool particleOcclusion = false;
|
bool particleOcclusion = false;
|
||||||
node.getUserValue("particleOcclusion", particleOcclusion);
|
node.getUserValue("particleOcclusion", particleOcclusion);
|
||||||
defineMap["particleOcclusion"]
|
defineMap["particleOcclusion"] = particleOcclusion && mWeatherParticleOcclusion ? "1" : "0";
|
||||||
= particleOcclusion && Settings::Manager::getBool("weather particle occlusion", "Shaders") ? "1" : "0";
|
|
||||||
|
|
||||||
if (reqs.mAlphaBlend && mSupportsNormalsRT)
|
if (reqs.mAlphaBlend && mSupportsNormalsRT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace Shader
|
||||||
|
|
||||||
void setSupportsNormalsRT(bool supports) { mSupportsNormalsRT = supports; }
|
void setSupportsNormalsRT(bool supports) { mSupportsNormalsRT = supports; }
|
||||||
|
|
||||||
|
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
|
||||||
|
|
||||||
void apply(osg::Node& node) override;
|
void apply(osg::Node& node) override;
|
||||||
|
|
||||||
void apply(osg::Drawable& drawable) override;
|
void apply(osg::Drawable& drawable) override;
|
||||||
|
@ -78,6 +80,7 @@ namespace Shader
|
||||||
bool mAdjustCoverageForAlphaTest;
|
bool mAdjustCoverageForAlphaTest;
|
||||||
|
|
||||||
bool mSupportsNormalsRT;
|
bool mSupportsNormalsRT;
|
||||||
|
bool mWeatherParticleOcclusion = false;
|
||||||
|
|
||||||
ShaderManager& mShaderManager;
|
ShaderManager& mShaderManager;
|
||||||
Resource::ImageManager& mImageManager;
|
Resource::ImageManager& mImageManager;
|
||||||
|
|
Loading…
Reference in a new issue