clear up force shaders and make it less convoluted

pull/3065/head
glassmancody.info 4 years ago
parent 8ce65232ff
commit 9e80091aff

@ -1,6 +1,6 @@
#include "advancedpage.hpp"
#include <unordered_map>
#include <array>
#include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp>
@ -256,7 +256,7 @@ void Launcher::AdvancedPage::saveSettings()
mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance));
}
static std::unordered_map<int, std::string> lightingMethodMap = {{0, "legacy"}, {1, "shaders compatibility"}, {2, "shaders"}};
static std::array<std::string, 3> lightingMethodMap = {"legacy", "shaders compatibility", "shaders"};
mEngineSettings.setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
}

@ -11,12 +11,15 @@
#include <iomanip>
#include <numeric>
#include <array>
#include <components/debug/debuglog.hpp>
#include <components/misc/stringops.hpp>
#include <components/misc/constants.hpp>
#include <components/widgets/sharedstatebutton.hpp>
#include <components/settings/settings.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/lightmanager.hpp>
#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<std::string> settings = {"light bounds multiplier", "maximum light distance", "light fade start", "minimum interior brightness", "max lights"};
constexpr std::array<const char*, 5> 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);
}

@ -19,6 +19,8 @@ namespace MWGui
void updateControlsBox();
void updateLightSettings();
void onResChange(int, int) override { center(); }
protected:

@ -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<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha);

@ -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<SceneUtil::LightManager> 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<SceneUtil::LightManager> 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();

@ -0,0 +1,15 @@
#ifndef MISC_HASH_H
#define MISC_HASH_H
namespace Misc
{
/// Implemented similar to the boost::hash_combine
template <class T>
inline void hashCombine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif

@ -1,5 +1,7 @@
#include "lightmanager.hpp"
#include <array>
#include <osg/BufferObject>
#include <osg/BufferIndexBinding>
#include <osg/Endian>
@ -8,20 +10,13 @@
#include <components/sceneutil/util.hpp>
#include <components/misc/hash.hpp>
#include <components/misc/stringops.hpp>
#include <components/debug/debuglog.hpp>
namespace
{
/* similar to the boost::hash_combine */
template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> 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<LayoutOffset, int> mOffsets;
std::array<std::size_t, 6> 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<unsigned int> index = { static_cast<int>(Shader::UBOBinding::LightBuffer) };
constexpr std::array<unsigned int, 1> index = { static_cast<unsigned int>(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<const char*> names = {
"LightBuffer[0].packedColors"
,"LightBuffer[0].position"
,"LightBuffer[0].attenuation"
std::array<const char*, 3> names = {
"LightBuffer[0].packedColors",
"LightBuffer[0].position",
"LightBuffer[0].attenuation",
};
std::vector<unsigned int> indices(names.size());
std::vector<int> 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<StateSetGeneratorPerObjectUniform>();
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;

@ -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;

@ -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

@ -529,7 +529,7 @@
<Widget type="TextBox" skin="NormalText" position="0 176 352 18" align="Left Top" name="BoundingSphereMultText">
<UserString key="ToolTipType" value="Layout"/>
<UserString key="ToolTipLayout" value="TextToolTip"/>
<UserString key="Caption_Text" value="Default: 1.75\nMultipler for bounding sphere of lights.\nHigher numbers allows for smooth falloff but require an increase in number of max lights.\n\nDoes not effect the illumination or strength of lights."/>
<UserString key="Caption_Text" value="Default: 1.65\nMultipler for bounding sphere of lights.\nHigher numbers allows for smooth falloff but require an increase in number of max lights.\n\nDoes not effect the illumination or strength of lights."/>
</Widget>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 200 352 18" align="HStretch Top">
<Property key="Range" value="500000"/>
@ -547,7 +547,7 @@
<Widget type="TextBox" skin="NormalText" position="0 224 352 18" align="Left Top" name="MinimumBrightnessText">
<UserString key="ToolTipType" value="Layout"/>
<UserString key="ToolTipLayout" value="TextToolTip"/>
<UserString key="Caption_Text" value="Default: 0.1\nMinimum ambient interior brightness.\n\nIncrease this if you feel interiors are too dark."/>
<UserString key="Caption_Text" value="Default: 0.08\nMinimum ambient interior brightness.\n\nIncrease this if you feel interiors are too dark."/>
</Widget>
<Widget type="ScrollBar" skin="MW_HScroll" position="0 248 352 18" align="HStretch Top">
<Property key="Range" value="10000"/>

@ -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.

@ -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

@ -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

Loading…
Cancel
Save