in-game settings, some require restart

pull/593/head
glassmancody.info 4 years ago
parent 3d713e8602
commit 71c30a31df

@ -6,6 +6,7 @@
#include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <MyGUI_TabControl.h>
#include <MyGUI_TabItem.h>
#include <SDL_video.h>
@ -17,6 +18,7 @@
#include <components/misc/constants.hpp>
#include <components/widgets/sharedstatebutton.hpp>
#include <components/settings/settings.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -107,7 +109,7 @@ namespace
namespace MWGui
{
void SettingsWindow::configureWidgets(MyGUI::Widget* widget)
void SettingsWindow::configureWidgets(MyGUI::Widget* widget, bool init)
{
MyGUI::EnumeratorWidgetPtr widgets = widget->getEnumerator();
while (widgets.next())
@ -121,7 +123,8 @@ namespace MWGui
getSettingCategory(current))
? "#{sOn}" : "#{sOff}";
current->castType<MyGUI::Button>()->setCaptionWithReplacing(initialValue);
current->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
if (init)
current->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
}
if (type == sliderType)
{
@ -141,6 +144,12 @@ namespace MWGui
ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits;
valueStr = ss.str();
}
else if (valueType == "Float")
{
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << value;
valueStr = ss.str();
}
else
valueStr = MyGUI::utility::toString(int(value));
@ -155,12 +164,13 @@ namespace MWGui
valueStr = MyGUI::utility::toString(value);
scroll->setScrollPosition(value);
}
scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
if (init)
scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
if (scroll->getVisible())
updateSliderLabel(scroll, valueStr);
}
configureWidgets(current);
configureWidgets(current, init);
}
}
@ -187,7 +197,7 @@ namespace MWGui
getWidget(unusedSlider, widgetName);
unusedSlider->setVisible(false);
configureWidgets(mMainWidget);
configureWidgets(mMainWidget, true);
setTitle("#{sOptions}");
@ -204,6 +214,9 @@ namespace MWGui
getWidget(mControllerSwitch, "ControllerButton");
getWidget(mWaterTextureSize, "WaterTextureSize");
getWidget(mWaterReflectionDetail, "WaterReflectionDetail");
getWidget(mLightingMethodButton, "LightingMethodButton");
getWidget(mMaxLightsSlider, "MaxLightsSlider");
getWidget(mLightsResetButton, "LightsResetButton");
#ifndef WIN32
// hide gamma controls since it currently does not work under Linux
@ -229,6 +242,9 @@ namespace MWGui
mWaterTextureSize->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterTextureSizeChanged);
mWaterReflectionDetail->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterReflectionDetailChanged);
mLightingMethodButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onLightingMethodChanged);
mLightsResetButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onLightsResetButtonClicked);
mKeyboardSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onKeyboardSwitchClicked);
mControllerSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onControllerSwitchClicked);
@ -272,6 +288,21 @@ namespace MWGui
waterReflectionDetail = std::min(5, std::max(0, waterReflectionDetail));
mWaterReflectionDetail->setIndexSelected(waterReflectionDetail);
auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders"));
switch (lightingMethod)
{
case SceneUtil::LightingMethod::Undefined:
case SceneUtil::LightingMethod::FFP:
mLightingMethodButton->setIndexSelected(0);
break;
case SceneUtil::LightingMethod::PerObjectUniform:
mLightingMethodButton->setIndexSelected(1);
break;
case SceneUtil::LightingMethod::SingleUBO:
mLightingMethodButton->setIndexSelected(2);
break;
}
mWindowBorderButton->setEnabled(!Settings::Manager::getBool("fullscreen", "Video"));
mKeyboardSwitch->setStateSelected(true);
@ -358,6 +389,49 @@ namespace MWGui
apply();
}
void SettingsWindow::onLightsResetButtonClicked(MyGUI::Widget* _sender)
{
std::vector<std::string> buttons = {"#{sYes}", "#{sNo}"};
std::string message = "This will reset all lighting settings to default, some changes will require a restart. Would you like to continue?";
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons, true);
int selectedButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
if (selectedButton == 1 || selectedButton == -1)
return;
Settings::Manager::setString("lighting method", "Shaders", "shaders compatibility");
Settings::Manager::setFloat("light bounds multiplier", "Shaders", 1.75);
Settings::Manager::setInt("maximum light distance", "Shaders", 8192);
Settings::Manager::setFloat("light fade start", "Shaders", 0.85);
Settings::Manager::setFloat("minimum interior brightness", "Shaders", 0.1);
Settings::Manager::setInt("max lights", "Shaders", 8);
mLightingMethodButton->setIndexSelected(1);
apply();
configureWidgets(mMainWidget, false);
}
void SettingsWindow::onLightingMethodChanged(MyGUI::ComboBox* _sender, size_t pos)
{
std::string setting;
auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(_sender->getItemNameAt(pos));
switch (lightingMethod)
{
case SceneUtil::LightingMethod::FFP:
setting = "legacy";
break;
case SceneUtil::LightingMethod::Undefined:
case SceneUtil::LightingMethod::PerObjectUniform:
setting = "shaders compatibility";
break;
case SceneUtil::LightingMethod::SingleUBO:
setting = "shaders";
break;
}
Settings::Manager::setString("lighting method", "Shaders", setting);
apply();
}
void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender)
{
std::string on = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOn", "On");
@ -460,6 +534,12 @@ namespace MWGui
ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits;
valueStr = ss.str();
}
else if (valueType == "Float")
{
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << value;
valueStr = ss.str();
}
else
valueStr = MyGUI::utility::toString(int(value));
}

@ -35,6 +35,10 @@ namespace MWGui
MyGUI::ComboBox* mWaterTextureSize;
MyGUI::ComboBox* mWaterReflectionDetail;
MyGUI::ComboBox* mLightingMethodButton;
MyGUI::ScrollBar* mMaxLightsSlider;
MyGUI::Button* mLightsResetButton;
// controls
MyGUI::ScrollView* mControlsBox;
MyGUI::Button* mResetControlsButton;
@ -55,6 +59,9 @@ namespace MWGui
void onWaterTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos);
void onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos);
void onLightsResetButtonClicked(MyGUI::Widget* _sender);
void onLightingMethodChanged(MyGUI::ComboBox* _sender, size_t pos);
void onRebindAction(MyGUI::Widget* _sender);
void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel);
void onResetDefaultBindings(MyGUI::Widget* _sender);
@ -66,7 +73,7 @@ namespace MWGui
void apply();
void configureWidgets(MyGUI::Widget* widget);
void configureWidgets(MyGUI::Widget* widget, bool init);
void updateSliderLabel(MyGUI::ScrollBar* scroller, const std::string& value);
void layoutControlsBox();

@ -52,6 +52,7 @@
#include "../mwgui/loadingscreen.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/actorutil.hpp"
#include "sky.hpp"
#include "effectmanager.hpp"
@ -224,8 +225,7 @@ namespace MWRender
resourceSystem->getSceneManager()->getShaderManager().setLightingMethod(sceneRoot->getLightingMethod());
resourceSystem->getSceneManager()->setLightingMethod(sceneRoot->getLightingMethod());
if (sceneRoot->getLightingMethod() != SceneUtil::LightingMethod::FFP)
mMinimumAmbientLuminance = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f);
mMinimumAmbientLuminance = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f);
sceneRoot->setLightingMask(Mask_Lighting);
mSceneRoot = sceneRoot;
@ -1144,9 +1144,25 @@ namespace MWRender
else if (it->first == "General" && (it->second == "texture filter" ||
it->second == "texture mipmap" ||
it->second == "anisotropy"))
{
updateTextureFiltering();
}
else if (it->first == "Water")
{
mWater->processChangedSettings(changed);
}
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().getCell())
configureAmbient(MWMechanics::getPlayer().getCell()->getCell());
}
else if (it->first == "Shaders" && (it->second == "light bounds multiplier" ||
it->second == "maximum light distance" ||
it->second == "light fade start"))
{
static_cast<SceneUtil::LightManager*>(getLightRoot())->processChangedSettings(changed);
}
}
}

@ -10,8 +10,6 @@
#include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp>
#include <components/debug/debuglog.hpp>
namespace
@ -41,6 +39,43 @@ namespace
{
light->setUserValue("radius", value);
}
void configurePosition(osg::Matrixf& mat, const osg::Vec4& pos)
{
mat(0, 0) = pos.x();
mat(0, 1) = pos.y();
mat(0, 2) = pos.z();
}
void configureAmbient(osg::Matrixf& mat, const osg::Vec4& color)
{
mat(1, 0) = color.r();
mat(1, 1) = color.g();
mat(1, 2) = color.b();
}
void configureDiffuse(osg::Matrixf& mat, const osg::Vec4& color)
{
mat(2, 0) = color.r();
mat(2, 1) = color.g();
mat(2, 2) = color.b();
}
void configureSpecular(osg::Matrixf& mat, const osg::Vec4& color)
{
mat(3, 0) = color.r();
mat(3, 1) = color.g();
mat(3, 2) = color.b();
mat(3, 3) = color.a();
}
void configureAttenuation(osg::Matrixf& mat, float c, float l, float q, float r)
{
mat(0, 3) = c;
mat(1, 3) = l;
mat(2, 3) = q;
mat(3, 3) = r;
}
}
namespace SceneUtil
@ -206,11 +241,12 @@ namespace SceneUtil
}
case LightingMethod::PerObjectUniform:
{
stateset->addUniform(new osg::Uniform("LightBuffer[0].diffuse", light->getDiffuse()), mode);
stateset->addUniform(new osg::Uniform("LightBuffer[0].ambient", light->getAmbient()), mode);
stateset->addUniform(new osg::Uniform("LightBuffer[0].specular", light->getSpecular()), mode);
stateset->addUniform(new osg::Uniform("LightBuffer[0].position", light->getPosition()), mode);
osg::Matrixf lightMat;
configurePosition(lightMat, light->getPosition());
configureAmbient(lightMat, light->getAmbient());
configureDiffuse(lightMat, light->getDiffuse());
configureSpecular(lightMat, light->getSpecular());
stateset->addUniform(new osg::Uniform("LightBuffer", lightMat), mode);
break;
}
case LightingMethod::SingleUBO:
@ -381,14 +417,20 @@ namespace SceneUtil
void apply(osg::State &state) const override
{
auto* lightUniform = mLightManager->getStateSet()->getUniform("LightBuffer");
for (size_t i = 0; i < mLights.size(); ++i)
{
auto light = mLights[i];
mLightManager->getLightUniform(i+1, LightManager::UniformKey::Diffuse)->set(light->getDiffuse());
mLightManager->getLightUniform(i+1, LightManager::UniformKey::Ambient)->set(light->getAmbient());
mLightManager->getLightUniform(i+1, LightManager::UniformKey::Attenuation)->set(osg::Vec4(light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(), getLightRadius(light)));
mLightManager->getLightUniform(i+1, LightManager::UniformKey::Position)->set(light->getPosition() * state.getInitialViewMatrix());
osg::Matrixf lightMat;
configurePosition(lightMat, light->getPosition() * state.getInitialViewMatrix());
configureAmbient(lightMat, light->getAmbient());
configureDiffuse(lightMat, light->getDiffuse());
configureAttenuation(lightMat, light->getConstantAttenuation(), light->getLinearAttenuation(), light->getQuadraticAttenuation(), getLightRadius(light));
lightUniform->setElement(i+1, lightMat);
}
lightUniform->dirty();
}
private:
@ -589,10 +631,12 @@ namespace SceneUtil
{
if (mLightManager->getLightingMethod() == LightingMethod::PerObjectUniform)
{
mLightManager->getLightUniform(0, LightManager::UniformKey::Diffuse)->set(sun->getDiffuse());
mLightManager->getLightUniform(0, LightManager::UniformKey::Ambient)->set(sun->getAmbient());
mLightManager->getLightUniform(0, LightManager::UniformKey::Specular)->set(sun->getSpecular());
mLightManager->getLightUniform(0, LightManager::UniformKey::Position)->set(sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
osg::Matrixf lightMat;
configurePosition(lightMat, sun->getPosition() * (*cv->getCurrentRenderStage()->getInitialViewMatrix()));
configureAmbient(lightMat, sun->getAmbient());
configureDiffuse(lightMat, sun->getDiffuse());
configureSpecular(lightMat, sun->getSpecular());
mLightManager->getStateSet()->getUniform("LightBuffer")->setElement(0, lightMat);
}
else
{
@ -760,14 +804,7 @@ namespace SceneUtil
lightingMethod = LightingMethod::PerObjectUniform;
}
mPointLightRadiusMultiplier = std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 10.f);
mPointLightFadeEnd = std::max(0.f, Settings::Manager::getFloat("maximum light distance", "Shaders"));
if (mPointLightFadeEnd > 0)
{
mPointLightFadeStart = std::clamp(Settings::Manager::getFloat("light fade start", "Shaders"), 0.f, 1.f);
mPointLightFadeStart = mPointLightFadeEnd * mPointLightFadeStart;
}
updateSettings();
osg::GLExtensions* exts = osg::GLExtensions::Get(0, false);
bool supportsUBO = exts && exts->isUniformBufferObjectSupported;
@ -839,9 +876,6 @@ namespace SceneUtil
{
Shader::ShaderManager::DefineMap defines;
bool ffp = usingFFP();
defines["ffpLighting"] = ffp ? "1" : "0";
defines["maxLights"] = std::to_string(getMaxLights());
defines["maxLightsInScene"] = std::to_string(getMaxLightsInScene());
defines["lightingModel"] = std::to_string(static_cast<int>(mLightingMethod));
@ -852,6 +886,26 @@ namespace SceneUtil
return defines;
}
void LightManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
updateSettings();
}
void LightManager::updateSettings()
{
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"));
if (mPointLightFadeEnd > 0)
{
mPointLightFadeStart = std::clamp(Settings::Manager::getFloat("light fade start", "Shaders"), 0.f, 1.f);
mPointLightFadeStart = mPointLightFadeEnd * mPointLightFadeStart;
}
}
void LightManager::initFFP(int targetLights)
{
setLightingMethod(LightingMethod::FFP);
@ -866,38 +920,15 @@ namespace SceneUtil
auto* stateset = getOrCreateStateSet();
setLightingMethod(LightingMethod::PerObjectUniform);
setMaxLights(std::max(2, targetLights));
setMaxLights(std::clamp(targetLights, 2, 64));
mLightUniforms.resize(getMaxLights()+1);
for (size_t i = 0; i < mLightUniforms.size(); ++i)
{
osg::ref_ptr<osg::Uniform> udiffuse = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].diffuse").c_str());
osg::ref_ptr<osg::Uniform> uspecular = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].specular").c_str());
osg::ref_ptr<osg::Uniform> uambient = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].ambient").c_str());
osg::ref_ptr<osg::Uniform> uposition = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].position").c_str());
osg::ref_ptr<osg::Uniform> uattenuation = new osg::Uniform(osg::Uniform::FLOAT_VEC4, ("LightBuffer[" + std::to_string(i) + "].attenuation").c_str());
mLightUniforms[i].emplace(UniformKey::Diffuse, udiffuse);
mLightUniforms[i].emplace(UniformKey::Ambient, uambient);
mLightUniforms[i].emplace(UniformKey::Specular, uspecular);
mLightUniforms[i].emplace(UniformKey::Position, uposition);
mLightUniforms[i].emplace(UniformKey::Attenuation, uattenuation);
stateset->addUniform(udiffuse);
stateset->addUniform(uambient);
stateset->addUniform(uposition);
stateset->addUniform(uattenuation);
// specular isn't used besides sun, complete waste to upload it
if (i == 0)
stateset->addUniform(uspecular);
}
stateset->addUniform(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "LightBuffer", getMaxLights() + 1));
}
void LightManager::initSingleUBO(int targetLights)
{
setLightingMethod(LightingMethod::SingleUBO);
setMaxLights(std::clamp(targetLights, 2, getMaxLightsInScene() / 2));
setMaxLights(std::clamp(targetLights, 2, 64));
for (int i = 0; i < 2; ++i)
{
@ -912,7 +943,6 @@ namespace SceneUtil
getOrCreateStateSet()->setAttribute(new LightManagerStateAttribute(this), osg::StateAttribute::ON);
}
void LightManager::setLightingMethod(LightingMethod method)
{
mLightingMethod = method;

@ -14,6 +14,8 @@
#include <components/shader/shadermanager.hpp>
#include <components/settings/settings.hpp>
namespace osgUtil
{
class CullVisitor;
@ -172,10 +174,10 @@ namespace SceneUtil
auto& getLightBuffer(size_t frameNum) { return mLightBuffers[frameNum%2]; }
auto& getLightUniform(int index, UniformKey key) { return mLightUniforms[index][key]; }
std::map<std::string, std::string> getLightDefines() const;
void processChangedSettings(const Settings::CategorySettingVector& changed);
private:
friend class LightManagerStateAttribute;
friend class LightManagerCullCallback;
@ -184,6 +186,8 @@ namespace SceneUtil
void initPerObjectUniform(int targetLights);
void initSingleUBO(int targetLights);
void updateSettings();
void setLightingMethod(LightingMethod method);
void setMaxLights(int value);
@ -212,9 +216,6 @@ namespace SceneUtil
using LightIndexMap = std::unordered_map<int, int>;
LightIndexMap mLightIndexMaps[2];
using UniformMap = std::vector<std::unordered_map<UniformKey, osg::ref_ptr<osg::Uniform>>>;
UniformMap mLightUniforms;
std::unique_ptr<StateSetGenerator> mStateSetGenerator;
LightingMethod mLightingMethod;

@ -185,7 +185,7 @@ light bounds multiplier
-----------------------
:Type: float
:Range: 0.0-10.0
:Range: 0.0-5.0
:Default: 1.75
Controls the bounding sphere radius of point lights, which is used to determine
@ -228,7 +228,7 @@ max lights
----------
:Type: integer
:Range: >=2
:Range: 2-64
:Default: 8
Sets the maximum number of lights that each object can receive lighting from.

@ -456,6 +456,95 @@
</Widget>
</Widget>
</Widget>
<Widget type="TabItem" skin="" position="4 32 360 308">
<Property key="Caption" value=" Lights "/>
<!-- Lighting Method -->
<Widget type="TextBox" skin="NormalText" position="0 4 160 18" align="Left Top">
<Property key="Caption" value="*Lighting Method"/>
</Widget>
<Widget type="ComboBox" skin="MW_ComboBox" position="0 28 170 24" align="Left Top" name="LightingMethodButton">
<Property key="AddItem" value="legacy"/>
<Property key="AddItem" value="shaders compatibility"/>
<Property key="AddItem" value="shaders"/>
</Widget>
<!-- Max Lights -->
<Widget type="TextBox" skin="NormalText" position="178 4 160 18" align="Left Top" name="MaxLightsText"/>
<Widget type="ScrollBar" skin="MW_HScroll" position="178 30 160 18" align="Right Top HStretch" name="MaxLightsSlider">
<Property key="Range" value="24"/>
<Property key="Page" value="1"/>
<UserString key="SettingType" value="Slider"/>
<UserString key="SettingMin" value="8"/>
<UserString key="SettingMax" value="32"/>
<UserString key="SettingCategory" value="Shaders"/>
<UserString key="SettingName" value="max lights"/>
<UserString key="SettingValueType" value="Integer"/>
<UserString key="SettingLabelWidget" value="MaxLightsText"/>
<UserString key="SettingLabelCaption" value="*Max Lights (%s)"/>
</Widget>
<Widget type="ImageBox" skin="MW_HLine" position="0 54 360 18" align="Top HStretch"/>
<!-- Light Fade Start -->
<Widget type="TextBox" skin="NormalText" position="0 78 352 18" align="Left Top" name="MaxLightDistanceText"/>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 104 352 18" align="HStretch Top">
<Property key="Range" value="8192"/>
<Property key="Page" value="1"/>
<UserString key="SettingType" value="Slider"/>
<UserString key="SettingMin" value="0"/>
<UserString key="SettingMax" value="8192"/>
<UserString key="SettingCategory" value="Shaders"/>
<UserString key="SettingName" value="maximum light distance"/>
<UserString key="SettingValueType" value="Integer"/>
<UserString key="SettingLabelWidget" value="MaxLightDistanceText"/>
<UserString key="SettingLabelCaption" value="Maximum Light Distance (%s)"/>
</Widget>
<!-- Light Fade Multiplier -->
<Widget type="TextBox" skin="NormalText" position="0 128 352 18" align="Left Top" name="LightFadeMultiplierText"/>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 152 352 18" align="HStretch Top">
<Property key="Range" value="10000"/>
<Property key="Page" value="300"/>
<UserString key="SettingType" value="Slider"/>
<UserString key="SettingCategory" value="Shaders"/>
<UserString key="SettingName" value="light fade start"/>
<UserString key="SettingValueType" value="Float"/>
<UserString key="SettingLabelWidget" value="LightFadeMultiplierText"/>
<UserString key="SettingLabelCaption" value="Fade Start Multiplier (%s)"/>
</Widget>
<!-- Bounding Sphere Multiplier -->
<Widget type="TextBox" skin="NormalText" position="0 176 352 18" align="Left Top" name="BoundingSphereMultText"/>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 200 352 18" align="HStretch Top">
<Property key="Range" value="10000"/>
<Property key="Page" value="300"/>
<UserString key="SettingType" value="Slider"/>
<UserString key="SettingMin" value="0.1"/>
<UserString key="SettingMax" value="5.0"/>
<UserString key="SettingCategory" value="Shaders"/>
<UserString key="SettingName" value="light bounds multiplier"/>
<UserString key="SettingValueType" value="Float"/>
<UserString key="SettingLabelWidget" value="BoundingSphereMultText"/>
<UserString key="SettingLabelCaption" value="Bounding Sphere Multiplier (%s)"/>
</Widget>
<!-- Minimum Ambient Brightness -->
<Widget type="TextBox" skin="NormalText" position="0 224 352 18" align="Left Top" name="MinimumBrightnessText"/>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 248 352 18" align="HStretch Top">
<Property key="Range" value="10000"/>
<Property key="Page" value="300"/>
<UserString key="SettingType" value="Slider"/>
<UserString key="SettingCategory" value="Shaders"/>
<UserString key="SettingName" value="minimum interior brightness"/>
<UserString key="SettingValueType" value="Float"/>
<UserString key="SettingLabelWidget" value="MinimumBrightnessText"/>
<UserString key="SettingLabelCaption" value="Minimum Interior Brightness (%s)"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="0 308 0 0" align="Bottom Left" name="LightsResetButton">
<Property key="Caption" value="Reset To Defaults"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="NormalText" position="210 308 0 0" align="Bottom Right HStretch">
<Property key="Caption" value="(*) Requires Restart"/>
<Property key="TextAlign" value="Right"/>
</Widget>
</Widget>
<!--
<Widget type="TabItem" skin="" position="0 28 352 268">

@ -2,7 +2,7 @@
#define LIGHTING_MODEL_SINGLE_UBO 1
#define LIGHTING_MODEL_PER_OBJECT_UNIFORM 2
#if !@ffpLighting
#if @lightingModel != LIGHTING_MODEL_FFP
#define getLight LightBuffer
float quickstep(float x)
@ -13,7 +13,7 @@ float quickstep(float x)
return x;
}
#if @useUBO
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
const int mask = int(0xff);
const ivec4 shift = ivec4(int(0), int(8), int(16), int(24));
@ -33,11 +33,16 @@ vec4 unpackRGBA(int data)
,(float(((data >> shift.w) & mask)) / 255.0));
}
/* Layout:
packedColors: 8-bit unsigned RGB packed as (diffuse, ambient, specular).
sign bit is stored in diffuse alpha component
attenuation: constant, linear, quadratic, light radius (as defined in content)
*/
struct LightData
{
ivec4 packedColors; // diffuse, ambient, specular
ivec4 packedColors;
vec4 position;
vec4 attenuation; // constant, linear, quadratic, radius
vec4 attenuation;
};
uniform int PointLightIndex[@maxLights];
@ -51,16 +56,15 @@ uniform LightBufferBinding
#else
struct LightData
{
vec4 position;
vec4 diffuse;
vec4 ambient;
vec4 specular;
vec4 attenuation; // constant, linear, quadratic, radius
};
uniform LightData LightBuffer[@maxLights];
/* Layout:
--------------------------------------- -----------
| pos_x | ambi_r | diff_r | spec_r |
| pos_y | ambi_g | diff_g | spec_g |
| pos_z | ambi_b | diff_b | spec_b |
| att_c | att_l | att_q | radius/spec_a |
--------------------------------------------------
*/
uniform mat4 LightBuffer[@maxLights];
uniform int PointLightCount;
#endif
@ -71,9 +75,16 @@ uniform int PointLightCount;
void perLightSun(out vec3 ambientOut, out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal)
{
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 lightDir = normalize(getLight[0][0].xyz);
#else
vec3 lightDir = normalize(getLight[0].position.xyz);
#endif
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
ambientOut = getLight[0][1].xyz;
vec3 sunDiffuse = getLight[0][2].xyz;
#elif @lightingModel == LIGHTING_MODEL_SINGLE_UBO
ivec4 data = getLight[0].packedColors;
ambientOut = unpackRGB(data.y);
vec3 sunDiffuse = unpackRGB(data.x);
@ -81,6 +92,7 @@ void perLightSun(out vec3 ambientOut, out vec3 diffuseOut, vec3 viewPos, vec3 vi
ambientOut = getLight[0].ambient.xyz;
vec3 sunDiffuse = getLight[0].diffuse.xyz;
#endif
float lambert = dot(viewNormal.xyz, lightDir);
#ifndef GROUNDCOVER
lambert = max(lambert, 0.0);
@ -98,13 +110,22 @@ void perLightSun(out vec3 ambientOut, out vec3 diffuseOut, vec3 viewPos, vec3 vi
void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal)
{
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 lightPos = getLight[lightIndex][0].xyz - viewPos;
#else
vec3 lightPos = getLight[lightIndex].position.xyz - viewPos;
#endif
float lightDistance = length(lightPos);
#if !@ffpLighting
// This has a *considerable* performance uplift where GPU is a bottleneck
if (lightDistance > getLight[lightIndex].attenuation.w * 2.0)
#if @lightingModel != LIGHTING_MODEL_FFP
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
float radius = getLight[lightIndex][3][3];
#else
float radius = getLight[lightIndex].attenuation.w;
#endif
if (lightDistance > radius * 2.0)
{
ambientOut = vec3(0.0);
diffuseOut = vec3(0.0);
@ -114,17 +135,17 @@ void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec
lightPos = normalize(lightPos);
#if @ffpLighting
float illumination = clamp(1.0 / (getLight[lightIndex].constantAttenuation + getLight[lightIndex].linearAttenuation * lightDistance + getLight[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0);
#else
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
float illumination = clamp(1.0 / (getLight[lightIndex][0].w + getLight[lightIndex][1].w * lightDistance + getLight[lightIndex][2].w * lightDistance * lightDistance), 0.0, 1.0);
illumination *= 1.0 - quickstep((lightDistance / radius) - 1.0);
ambientOut = getLight[lightIndex][1].xyz * illumination;
#elif @lightingModel == LIGHTING_MODEL_SINGLE_UBO
float illumination = clamp(1.0 / (getLight[lightIndex].attenuation.x + getLight[lightIndex].attenuation.y * lightDistance + getLight[lightIndex].attenuation.z * lightDistance * lightDistance), 0.0, 1.0);
illumination *= 1.0 - quickstep((lightDistance / (getLight[lightIndex].attenuation.w)) - 1.0);
#endif
#if @useUBO
illumination *= 1.0 - quickstep((lightDistance / radius) - 1.0);
ivec4 data = getLight[lightIndex].packedColors;
ambientOut = unpackRGB(data.y) * illumination;
#else
float illumination = clamp(1.0 / (getLight[lightIndex].constantAttenuation + getLight[lightIndex].linearAttenuation * lightDistance + getLight[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0);
ambientOut = getLight[lightIndex].ambient.xyz * illumination;
#endif
@ -142,8 +163,10 @@ 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
#if @useUBO
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
diffuseOut = unpackRGB(data.x) * lambert * float(int(data.w));
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
diffuseOut = getLight[lightIndex][2].xyz * lambert;
#else
diffuseOut = getLight[lightIndex].diffuse.xyz * lambert;
#endif
@ -191,10 +214,16 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a
vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matSpec)
{
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 sunDir = getLight[0][0].xyz;
#else
vec3 sunDir = getLight[0].position.xyz;
#endif
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
vec3 sunSpec = unpackRGB(getLight[0].packedColors.z);
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 sunSpec = getLight[0][3].xyz;
#else
vec3 sunSpec = getLight[0].specular.xyz;
#endif

@ -203,8 +203,11 @@ void main(void)
normal3 * midWaves.y + normal4 * smallWaves.x + normal5 * smallWaves.y + rippleAdd);
normal = normalize(vec3(-normal.x * bump, -normal.y * bump, normal.z));
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 lVec = normalize((gl_ModelViewMatrixInverse * vec4(getLight[0][0].xyz, 0.0)).xyz);
#else
vec3 lVec = normalize((gl_ModelViewMatrixInverse * vec4(getLight[0].position.xyz, 0.0)).xyz);
#endif
vec3 cameraPos = (gl_ModelViewMatrixInverse * vec4(0,0,0,1)).xyz;
vec3 vVec = normalize(position.xyz - cameraPos.xyz);
@ -241,6 +244,8 @@ void main(void)
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
vec4 sunSpec = unpackRGBA(getLight[0].packedColors.z);
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec4 sunSpec = getLight[0][3];
#else
vec4 sunSpec = getLight[0].specular;
#endif

Loading…
Cancel
Save