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