diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 20cd38cbb..c9ea69cc7 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -1,6 +1,6 @@ #include "advancedpage.hpp" -#include +#include #include #include @@ -256,7 +256,7 @@ void Launcher::AdvancedPage::saveSettings() mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance)); } - static std::unordered_map lightingMethodMap = {{0, "legacy"}, {1, "shaders compatibility"}, {2, "shaders"}}; + static std::array lightingMethodMap = {"legacy", "shaders compatibility", "shaders"}; mEngineSettings.setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]); } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index b5d8c1089..e703316da 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -11,12 +11,15 @@ #include #include +#include #include #include #include #include #include +#include +#include #include #include "../mwbase/environment.hpp" @@ -104,6 +107,22 @@ namespace if (!widget->getUserString(settingMax).empty()) max = MyGUI::utility::parseFloat(widget->getUserString(settingMax)); } + + const char* getLightingMethodCaptionText(SceneUtil::LightingMethod lightingMethod) + { + switch (lightingMethod) + { + case SceneUtil::LightingMethod::FFP: + return "Emulates fixed function pipeline lighting, advanced light settings are disabled when this mode is active"; + case SceneUtil::LightingMethod::PerObjectUniform: + return "Removes limit of 8 lights per object, fixes lighting attenuation, and enables groundcover lighting and light fade." + "\n\nDesigned for compatibility across hardware, and is not meant for large max light counts."; + case SceneUtil::LightingMethod::SingleUBO: + return "Removes limit of 8 lights per object, fixes lighting attenuation, and enables groundcover lighting and light fade." + "\n\nDesigned for more modern hardware and large max light counts."; + } + return ""; + } } namespace MWGui @@ -286,36 +305,6 @@ namespace MWGui waterReflectionDetail = std::min(5, std::max(0, waterReflectionDetail)); mWaterReflectionDetail->setIndexSelected(waterReflectionDetail); - auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders")); - mLightingMethodText->setCaption(SceneUtil::LightManager::getLightingMethodString(lightingMethod)); - - if (lightingMethod == SceneUtil::LightingMethod::FFP || !Settings::Manager::getBool("force shaders", "Shaders")) - { - MyGUI::Widget* parent = mLightSettingOverlay->getParent(); - mLightSettingOverlay->setEnabled(false); - mLightSettingOverlay->setAlpha(0.8); - parent->setUserString("ToolTipType", "Layout"); - parent->setUserString("ToolTipLayout", "TextToolTip"); - parent->setUserString("Caption_Text", "Unavailable with current settings."); - parent->setEnabled(true); - } - else - { - std::string captionText; - if (lightingMethod == SceneUtil::LightingMethod::FFP) - captionText = - "Emulates fixed function pipeline lighting, advanced light settings are disabled when this mode is active"; - else if (lightingMethod == SceneUtil::LightingMethod::PerObjectUniform) - captionText = - "Removes limit of 8 lights per object, fixes lighting attenuation, and enables groundcover lighting and light fade." - "\n\nDesigned for compatibility across hardware, and is not meant for large max light counts."; - else if (lightingMethod == SceneUtil::LightingMethod::SingleUBO) - captionText = - "Removes limit of 8 lights per object, fixes lighting attenuation, and enables groundcover lighting and light fade." - "\n\nDesigned for more modern hardware and large max light counts."; - mLightingMethodText->setUserString("Caption_Text", captionText); - } - mWindowBorderButton->setEnabled(!Settings::Manager::getBool("fullscreen", "Video")); mKeyboardSwitch->setStateSelected(true); @@ -411,7 +400,7 @@ namespace MWGui if (selectedButton == 1 || selectedButton == -1) return; - const std::vector settings = {"light bounds multiplier", "maximum light distance", "light fade start", "minimum interior brightness", "max lights"}; + constexpr std::array settings = {"light bounds multiplier", "maximum light distance", "light fade start", "minimum interior brightness", "max lights"}; for (const auto& setting : settings) Settings::Manager::setString(setting, "Shaders", Settings::Manager::mDefaultSettings[{"Shaders", setting}]); @@ -617,6 +606,25 @@ namespace MWGui layoutControlsBox(); } + void SettingsWindow::updateLightSettings() + { + auto lightingMethod = MWBase::Environment::get().getResourceSystem()->getSceneManager()->getLightingMethod(); + mLightingMethodText->setCaption(SceneUtil::LightManager::getLightingMethodString(lightingMethod)); + + if (lightingMethod == SceneUtil::LightingMethod::FFP || !Settings::Manager::getBool("force shaders", "Shaders")) + { + MyGUI::Widget* parent = mLightSettingOverlay->getParent(); + mLightSettingOverlay->setEnabled(false); + mLightSettingOverlay->setAlpha(0.8); + parent->setUserString("ToolTipType", "Layout"); + parent->setUserString("ToolTipLayout", "TextToolTip"); + parent->setUserString("Caption_Text", "Unavailable with current settings."); + parent->setEnabled(true); + } + + mLightingMethodText->setUserString("Caption_Text", getLightingMethodCaptionText(lightingMethod)); + } + void SettingsWindow::layoutControlsBox() { const int h = 18; @@ -679,6 +687,7 @@ namespace MWGui { highlightCurrentResolution(); updateControlsBox(); + updateLightSettings(); resetScrollbars(); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton); } diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 219c55c96..d3b864c43 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -19,6 +19,8 @@ namespace MWGui void updateControlsBox(); + void updateLightSettings(); + void onResChange(int, int) override { center(); } protected: diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 79447676e..b578ee25b 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -522,7 +522,7 @@ namespace MWRender stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override { osg::Material* material = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ba1dca80e..ac32605a0 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -201,17 +201,14 @@ namespace MWRender , mFieldOfViewOverridden(false) , mFieldOfViewOverride(0.f) { - auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders")); - bool usingFFPLighting = lightingMethod == SceneUtil::LightingMethod::FFP; - resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); resourceSystem->getSceneManager()->setShaderPath(resourcePath + "/shaders"); + bool explicitlyForceShaders = Settings::Manager::getBool("force shaders", "Shaders"); // Shadows and radial fog have problems with fixed-function mode - bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("enable shadows", "Shadows") || usingFFPLighting; - bool clampLighting = Settings::Manager::getBool("clamp lighting", "Shaders"); + bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") || explicitlyForceShaders || Settings::Manager::getBool("enable shadows", "Shadows"); resourceSystem->getSceneManager()->setForceShaders(forceShaders); // FIXME: calling dummy method because terrain needs to know whether lighting is clamped - resourceSystem->getSceneManager()->setClampLighting(clampLighting); + 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")); @@ -220,11 +217,11 @@ namespace MWRender 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); - osg::ref_ptr sceneRoot = new SceneUtil::LightManager(!forceShaders || usingFFPLighting); - // Let LightManager choose which backend to use based on our hint, mostly depends on support for UBOs + auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders")); + // 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 sceneRoot = new SceneUtil::LightManager(!explicitlyForceShaders || lightingMethod == SceneUtil::LightingMethod::FFP); resourceSystem->getSceneManager()->getShaderManager().setLightingMethod(sceneRoot->getLightingMethod()); resourceSystem->getSceneManager()->setLightingMethod(sceneRoot->getLightingMethod()); - Settings::Manager::setString("lighting method", "Shaders", SceneUtil::LightManager::getLightingMethodString(sceneRoot->getLightingMethod())); mMinimumAmbientLuminance = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f); @@ -546,9 +543,9 @@ namespace MWRender if (needsAdjusting) { - static constexpr float pR = 0.2126; - static constexpr float pG = 0.7152; - static constexpr float pB = 0.0722; + constexpr float pR = 0.2126; + constexpr float pG = 0.7152; + constexpr float pB = 0.0722; // 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(); diff --git a/components/misc/hash.hpp b/components/misc/hash.hpp new file mode 100644 index 000000000..30a9c41ee --- /dev/null +++ b/components/misc/hash.hpp @@ -0,0 +1,15 @@ +#ifndef MISC_HASH_H +#define MISC_HASH_H + +namespace Misc +{ + /// Implemented similar to the boost::hash_combine + template + inline void hashCombine(std::size_t& seed, const T& v) + { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } +} + +#endif \ No newline at end of file diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index 4b9549c10..bc13559b1 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -1,5 +1,7 @@ #include "lightmanager.hpp" +#include + #include #include #include @@ -8,20 +10,13 @@ #include +#include #include #include namespace { - /* similar to the boost::hash_combine */ - template - inline void hash_combine(std::size_t& seed, const T& v) - { - std::hash hasher; - seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); - } - bool sortLights(const SceneUtil::LightManager::LightSourceViewBound* left, const SceneUtil::LightManager::LightSourceViewBound* right) { static auto constexpr illuminationBias = 81.f; @@ -124,39 +119,37 @@ namespace SceneUtil { // Deal with negative lights (negative diffuse) by passing a sign bit in the unused alpha component auto positiveColor = value; - float signBit = 1.0; + unsigned int signBit = 1; if (value[0] < 0) { positiveColor *= -1.0; - signBit = -1.0; + signBit = -1; } - *(unsigned int*)(&(*mData)[getOffset(index, Diffuse)]) = asRGBA(positiveColor); - *(int*)(&(*mData)[getOffset(index, DiffuseSign)]) = signBit; + unsigned int packedColor = asRGBA(positiveColor); + std::memcpy(&(*mData)[getOffset(index, Diffuse)], &packedColor, sizeof(unsigned int)); + std::memcpy(&(*mData)[getOffset(index, DiffuseSign)], &signBit, sizeof(unsigned int)); } void setAmbient(int index, const osg::Vec4& value) { - *(unsigned int*)(&(*mData)[getOffset(index, Ambient)]) = asRGBA(value); + unsigned int packed = asRGBA(value); + std::memcpy(&(*mData)[getOffset(index, Ambient)], &packed, sizeof(unsigned int)); } void setSpecular(int index, const osg::Vec4& value) { - *(unsigned int*)(&(*mData)[getOffset(index, Specular)]) = asRGBA(value); + unsigned int packed = asRGBA(value); + std::memcpy(&(*mData)[getOffset(index, Specular)], &packed, sizeof(unsigned int)); } void setPosition(int index, const osg::Vec4& value) { - *(osg::Vec4*)(&(*mData)[getOffset(index, Position)]) = value; + std::memcpy(&(*mData)[getOffset(index, Position)], value.ptr(), sizeof(osg::Vec4f)); } void setAttenuationRadius(int index, const osg::Vec4& value) { - *(osg::Vec4*)(&(*mData)[getOffset(index, AttenuationRadius)]) = value; - } - - auto getPosition(int index) - { - return *(osg::Vec4*)(&(*mData)[getOffset(index, Position)]); + std::memcpy(&(*mData)[getOffset(index, AttenuationRadius)], value.ptr(), sizeof(osg::Vec4f)); } auto& getData() @@ -186,8 +179,8 @@ namespace SceneUtil void configureLayout(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride) { - static constexpr auto sizeofVec4 = sizeof(GL_FLOAT) * osg::Vec4::num_components; - static constexpr auto sizeofFloat = sizeof(GL_FLOAT); + constexpr auto sizeofVec4 = sizeof(GL_FLOAT) * osg::Vec4::num_components; + constexpr auto sizeofFloat = sizeof(GL_FLOAT); mOffsets[Diffuse] = offsetColors / sizeofFloat; mOffsets[Ambient] = mOffsets[Diffuse] + 1; @@ -201,9 +194,9 @@ namespace SceneUtil LightBuffer oldBuffer = LightBuffer(*this); for (int i = 0; i < oldBuffer.mCount; ++i) { - *(osg::Vec4*)(&(*mData)[getOffset(i, Diffuse)]) = *(osg::Vec4*)(&(*mData)[oldBuffer.getOffset(i, Diffuse)]); - *(osg::Vec4*)(&(*mData)[getOffset(i, Position)]) = *(osg::Vec4*)(&(*mData)[oldBuffer.getOffset(i, Position)]); - *(osg::Vec4*)(&(*mData)[getOffset(i, AttenuationRadius)]) = *(osg::Vec4*)(&(*mData)[oldBuffer.getOffset(i, AttenuationRadius)]); + std::memcpy(&(*mData)[getOffset(i, Diffuse)], &(*mData)[oldBuffer.getOffset(i, Diffuse)], sizeof(osg::Vec4f)); + std::memcpy(&(*mData)[getOffset(i, Position)], &(*mData)[oldBuffer.getOffset(i, Position)], sizeof(osg::Vec4f)); + std::memcpy(&(*mData)[getOffset(i, AttenuationRadius)], &(*mData)[oldBuffer.getOffset(i, AttenuationRadius)], sizeof(osg::Vec4f)); } } @@ -212,7 +205,7 @@ namespace SceneUtil osg::Endian mEndian; int mCount; int mStride; - std::unordered_map mOffsets; + std::array mOffsets; }; class LightStateCache @@ -234,7 +227,6 @@ namespace SceneUtil { switch (method) { - case LightingMethod::Undefined: case LightingMethod::FFP: { break; @@ -304,9 +296,9 @@ namespace SceneUtil void apply(osg::State& state) const override { int lightNum = GL_LIGHT0 + mIndex; - glLightfv(lightNum, GL_AMBIENT, mnullptr.ptr()); - glLightfv(lightNum, GL_DIFFUSE, mnullptr.ptr()); - glLightfv(lightNum, GL_SPECULAR, mnullptr.ptr()); + glLightfv(lightNum, GL_AMBIENT, mNullptr.ptr()); + glLightfv(lightNum, GL_DIFFUSE, mNullptr.ptr()); + glLightfv(lightNum, GL_SPECULAR, mNullptr.ptr()); LightStateCache* cache = getLightStateCache(state.getContextID()); cache->lastAppliedLight[mIndex] = nullptr; @@ -314,7 +306,7 @@ namespace SceneUtil private: size_t mIndex; - osg::Vec4f mnullptr; + osg::Vec4f mNullptr; }; class FFPLightStateAttribute : public osg::StateAttribute @@ -697,17 +689,17 @@ namespace SceneUtil void initSharedLayout(osg::GLExtensions* ext, int handle) const { - std::vector index = { static_cast(Shader::UBOBinding::LightBuffer) }; + constexpr std::array index = { static_cast(Shader::UBOBinding::LightBuffer) }; int totalBlockSize = -1; int stride = -1; ext->glGetActiveUniformBlockiv(handle, 0, GL_UNIFORM_BLOCK_DATA_SIZE, &totalBlockSize); ext->glGetActiveUniformsiv(handle, index.size(), index.data(), GL_UNIFORM_ARRAY_STRIDE, &stride); - std::vector names = { - "LightBuffer[0].packedColors" - ,"LightBuffer[0].position" - ,"LightBuffer[0].attenuation" + std::array names = { + "LightBuffer[0].packedColors", + "LightBuffer[0].position", + "LightBuffer[0].attenuation", }; std::vector indices(names.size()); std::vector offsets(names.size()); @@ -803,18 +795,15 @@ namespace SceneUtil ,{"shaders", LightingMethod::SingleUBO} }; - bool LightManager::isValidLightingModelString(const std::string& value) - { - return LightManager::mLightingMethodSettingMap.find(value) != LightManager::mLightingMethodSettingMap.end(); - } - LightingMethod LightManager::getLightingMethodFromString(const std::string& value) { auto it = LightManager::mLightingMethodSettingMap.find(value); if (it != LightManager::mLightingMethodSettingMap.end()) return it->second; - else - return LightingMethod::Undefined; + + constexpr const char* fallback = "shaders compatibility"; + Log(Debug::Warning) << "Unknown lighting method '" << value << "', returning fallback '" << fallback << "'"; + return LightingMethod::PerObjectUniform; } std::string LightManager::getLightingMethodString(LightingMethod method) @@ -843,12 +832,6 @@ namespace SceneUtil std::string lightingMethodString = Settings::Manager::getString("lighting method", "Shaders"); auto lightingMethod = LightManager::getLightingMethodFromString(lightingMethodString); - if (lightingMethod == LightingMethod::Undefined) - { - Log(Debug::Error) << "Invalid option for 'lighting method': got '" << lightingMethodString - << "', expected legacy, shaders compatible, or shaders. Falling back to 'shaders compatible'."; - lightingMethod = LightingMethod::PerObjectUniform; - } updateSettings(); @@ -875,7 +858,6 @@ namespace SceneUtil initSingleUBO(targetLights); getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0)); - getOrCreateStateSet()->setAttributeAndModes(new LightManagerStateAttributePerObjectUniform(this), osg::StateAttribute::ON); addCullCallback(new LightManagerCullCallback(this)); } @@ -894,10 +876,6 @@ namespace SceneUtil return mLightingMethod; } - LightManager::~LightManager() - { - } - bool LightManager::usingFFP() const { return mLightingMethod == LightingMethod::FFP; @@ -1029,6 +1007,7 @@ namespace SceneUtil setLightingMethod(LightingMethod::PerObjectUniform); setMaxLights(std::clamp(targetLights, mMaxLightsLowerLimit, LightManager::mMaxLightsUpperLimit)); + stateset->setAttributeAndModes(new LightManagerStateAttributePerObjectUniform(this), osg::StateAttribute::ON); stateset->addUniform(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "LightBuffer", getMaxLights())); } @@ -1064,9 +1043,6 @@ namespace SceneUtil case LightingMethod::PerObjectUniform: mStateSetGenerator = std::make_unique(); break; - case LightingMethod::Undefined: - mStateSetGenerator = nullptr; - break; } mStateSetGenerator->mLightManager = this; } @@ -1107,7 +1083,7 @@ namespace SceneUtil getLightIndexMap(frameNum).clear(); mLights.clear(); mLightsInViewSpace.clear(); - return; + // Do an occasional cleanup for orphaned lights. for (int i = 0; i < 2; ++i) { @@ -1146,7 +1122,7 @@ namespace SceneUtil for (size_t i = 0; i < lightList.size(); ++i) { auto id = lightList[i]->mLightSource->getId(); - hash_combine(hash, id); + Misc::hashCombine(hash, id); if (getLightingMethod() != LightingMethod::SingleUBO) continue; diff --git a/components/sceneutil/lightmanager.hpp b/components/sceneutil/lightmanager.hpp index 62620c61f..9a1fd5470 100644 --- a/components/sceneutil/lightmanager.hpp +++ b/components/sceneutil/lightmanager.hpp @@ -31,7 +31,6 @@ namespace SceneUtil FFP, PerObjectUniform, SingleUBO, - Undefined }; void configureStateSetSunOverride(LightingMethod method, const osg::Light* light, osg::StateSet* stateset, int mode = osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); @@ -114,7 +113,6 @@ namespace SceneUtil class LightManager : public osg::Group { public: - static bool isValidLightingModelString(const std::string& value); static LightingMethod getLightingMethodFromString(const std::string& value); /// Returns string as used in settings file, or the empty string if the method is undefined static std::string getLightingMethodString(LightingMethod method); @@ -139,8 +137,6 @@ namespace SceneUtil LightManager(const LightManager& copy, const osg::CopyOp& copyop); - ~LightManager(); - /// @param mask This mask is compared with the current Camera's cull mask to determine if lighting is desired. /// By default, it's ~0u i.e. always on. /// If you have some views that do not require lighting, then set the Camera's cull mask to not include @@ -233,7 +229,6 @@ namespace SceneUtil float mPointLightRadiusMultiplier; float mPointLightFadeEnd; float mPointLightFadeStart; - float mPointLightFadeDelta; int mMaxLights; diff --git a/docs/source/reference/modding/settings/shaders.rst b/docs/source/reference/modding/settings/shaders.rst index 0537332a8..fc3767f8e 100644 --- a/docs/source/reference/modding/settings/shaders.rst +++ b/docs/source/reference/modding/settings/shaders.rst @@ -186,7 +186,7 @@ light bounds multiplier :Type: float :Range: 0.0-5.0 -:Default: 1.75 +:Default: 1.65 Controls the bounding sphere radius of point lights, which is used to determine if an object should receive lighting from a particular light source. Note, this @@ -243,7 +243,7 @@ minimum interior brightness :Type: float :Range: 0.0-1.0 -:Default: 0.1 +:Default: 0.08 Sets the minimum interior ambient brightness for interior cells when :ref:`lighting method` is not 'legacy'. A consequence of the new lighting system diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 400cba07f..11ad9fd39 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -529,7 +529,7 @@ - + @@ -547,7 +547,7 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index de2c237e8..72118459f 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -456,7 +456,7 @@ lighting method = shaders compatibility # lighting. Higher values will allow for smoother transitions of light sources, # but may carry a performance cost and requires a higher number of 'max lights' # set. -light bounds multiplier = 1.75 +light bounds multiplier = 1.65 # The distance from the camera at which lights fade away completely. # Set to 0 to disable fading. @@ -472,7 +472,7 @@ max lights = 8 # Sets minimum ambient brightness of interior cells. Levels below this threshold will have their # ambient values adjusted to balance the darker interiors. # When 'lighting method' is set to 'legacy', this setting will have no effect. -minimum interior brightness = 0.1 +minimum interior brightness = 0.08 # Convert the alpha test (cutout/punchthrough alpha) to alpha-to-coverage. # This allows MSAA to work with alpha-tested meshes, producing better-looking edges without pixelation. diff --git a/files/shaders/lighting.glsl b/files/shaders/lighting.glsl index ff8fa8969..49e2c3261 100644 --- a/files/shaders/lighting.glsl +++ b/files/shaders/lighting.glsl @@ -56,7 +56,7 @@ void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0); #endif - diffuseOut = lcalcDiffuse(lightIndex) * lambert; + diffuseOut = lcalcDiffuse(lightIndex) * lambert; } #if PER_PIXEL_LIGHTING diff --git a/files/shaders/lighting_util.glsl b/files/shaders/lighting_util.glsl index 6277d9d0b..be3225907 100644 --- a/files/shaders/lighting_util.glsl +++ b/files/shaders/lighting_util.glsl @@ -102,7 +102,7 @@ vec3 lcalcDiffuse(int lightIndex) #if @lightingMethodPerObjectUniform return @getLight[lightIndex][2].xyz; #elif @lightingMethodUBO - return unpackRGB(@getLight[lightIndex].packedColors.x) * float(int(@getLight[lightIndex].packedColors.w)); + return unpackRGB(@getLight[lightIndex].packedColors.x) * float(@getLight[lightIndex].packedColors.w); #else return @getLight[lightIndex].diffuse.xyz; #endif