mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 03:15:32 +00:00
Fix incorrect minimum ambient
This commit is contained in:
parent
280fd2b162
commit
3d713e8602
5 changed files with 65 additions and 76 deletions
|
@ -49,6 +49,7 @@ Programmers
|
|||
Cédric Mocquillon
|
||||
Chris Boyce (slothlife)
|
||||
Chris Robinson (KittyCat)
|
||||
Cody Glassman (Wazabear)
|
||||
Coleman Smith (olcoal)
|
||||
Cory F. Cohen (cfcohen)
|
||||
Cris Mihalache (Mirceam)
|
||||
|
|
|
@ -537,7 +537,32 @@ namespace MWRender
|
|||
|
||||
void RenderingManager::configureAmbient(const ESM::Cell *cell)
|
||||
{
|
||||
setAmbientColour(SceneUtil::colourFromRGB(cell->mAmbi.mAmbient));
|
||||
bool needsAdjusting = false;
|
||||
if (mResourceSystem->getSceneManager()->getLightingMethod() != SceneUtil::LightingMethod::FFP)
|
||||
needsAdjusting = !cell->isExterior() && !(cell->mData.mFlags & ESM::Cell::QuasiEx);
|
||||
|
||||
auto ambient = SceneUtil::colourFromRGB(cell->mAmbi.mAmbient);
|
||||
|
||||
if (needsAdjusting)
|
||||
{
|
||||
static constexpr float pR = 0.2126;
|
||||
static constexpr float pG = 0.7152;
|
||||
static 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();
|
||||
if (relativeLuminance < mMinimumAmbientLuminance)
|
||||
{
|
||||
// brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data as least we can
|
||||
float targetBrightnessIncreaseFactor = mMinimumAmbientLuminance / relativeLuminance;
|
||||
if (ambient.r() == 0.f && ambient.g() == 0.f && ambient.b() == 0.f)
|
||||
ambient = osg::Vec4(targetBrightnessIncreaseFactor, targetBrightnessIncreaseFactor, targetBrightnessIncreaseFactor, ambient.a());
|
||||
else
|
||||
ambient *= targetBrightnessIncreaseFactor;
|
||||
}
|
||||
}
|
||||
|
||||
setAmbientColour(ambient);
|
||||
|
||||
osg::Vec4f diffuse = SceneUtil::colourFromRGB(cell->mAmbi.mSunlight);
|
||||
mSunLight->setDiffuse(diffuse);
|
||||
|
@ -1076,25 +1101,7 @@ namespace MWRender
|
|||
osg::Vec4f color = mAmbientColor;
|
||||
|
||||
if (mNightEyeFactor > 0.f)
|
||||
{
|
||||
color += osg::Vec4f(0.7, 0.7, 0.7, 0.0) * mNightEyeFactor;
|
||||
}
|
||||
// optionally brighten up ambient interiors when using a non-FFP emulated lighting method
|
||||
else if (mResourceSystem->getSceneManager()->getLightingMethod() != SceneUtil::LightingMethod::FFP)
|
||||
{
|
||||
static constexpr float pR = 0.2126;
|
||||
static constexpr float pG = 0.7152;
|
||||
static constexpr float pB = 0.0722;
|
||||
|
||||
// we already work in linear RGB so no conversions are needed for the luminosity function
|
||||
float relativeLuminance = pR*color.r() + pG*color.g() + pB*color.b();
|
||||
if (relativeLuminance < mMinimumAmbientLuminance)
|
||||
{
|
||||
// brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data as least we can
|
||||
float targetBrightnessIncreaseFactor = mMinimumAmbientLuminance / relativeLuminance;
|
||||
color *= targetBrightnessIncreaseFactor;
|
||||
}
|
||||
}
|
||||
|
||||
mStateUpdater->setAmbientColor(color);
|
||||
}
|
||||
|
|
|
@ -381,27 +381,14 @@ namespace SceneUtil
|
|||
|
||||
void apply(osg::State &state) const override
|
||||
{
|
||||
osg::Matrix modelViewMatrix = state.getModelViewMatrix();
|
||||
|
||||
state.applyModelViewMatrix(state.getInitialViewMatrix());
|
||||
|
||||
LightStateCache* cache = getLightStateCache(state.getContextID(), mLightManager->getMaxLights());
|
||||
for (size_t i = 0; i < mLights.size(); ++i)
|
||||
{
|
||||
osg::Light* current = cache->lastAppliedLight[i];
|
||||
auto light = mLights[i];
|
||||
if (current != light.get())
|
||||
{
|
||||
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.getModelViewMatrix());
|
||||
|
||||
cache->lastAppliedLight[i] = 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());
|
||||
}
|
||||
|
||||
state.applyModelViewMatrix(modelViewMatrix);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -643,7 +630,7 @@ namespace SceneUtil
|
|||
mDummyProgram->addBindUniformBlock("LightBufferBinding", static_cast<int>(Shader::UBOBinding::LightBuffer));
|
||||
// Needed to query the layout of the buffer object. The layout specifier needed to use the std140 layout is not reliably
|
||||
// available, regardless of extensions, until GLSL 140.
|
||||
mLightManager->getOrCreateStateSet()->setAttributeAndModes(mDummyProgram, osg::StateAttribute::ON|osg::StateAttribute::PROTECTED);
|
||||
mLightManager->getOrCreateStateSet()->setAttributeAndModes(mDummyProgram, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
LightManagerStateAttribute(const LightManagerStateAttribute& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
|
||||
|
@ -756,9 +743,10 @@ namespace SceneUtil
|
|||
, mPointLightFadeEnd(0.f)
|
||||
, mPointLightFadeStart(0.f)
|
||||
{
|
||||
setUpdateCallback(new LightManagerUpdateCallback);
|
||||
|
||||
if (ffp)
|
||||
{
|
||||
setLightingMethod(LightingMethod::FFP);
|
||||
initFFP(LightManager::mFFPMaxLights);
|
||||
return;
|
||||
}
|
||||
|
@ -769,11 +757,7 @@ namespace SceneUtil
|
|||
{
|
||||
Log(Debug::Error) << "Invalid option for 'lighting method': got '" << lightingMethodString
|
||||
<< "', expected legacy, shaders compatible, or shaders. Falling back to 'shaders compatible'.";
|
||||
setLightingMethod(LightingMethod::PerObjectUniform);
|
||||
}
|
||||
else
|
||||
{
|
||||
setLightingMethod(lightingMethod);
|
||||
lightingMethod = LightingMethod::PerObjectUniform;
|
||||
}
|
||||
|
||||
mPointLightRadiusMultiplier = std::clamp(Settings::Manager::getFloat("light bounds multiplier", "Shaders"), 0.f, 10.f);
|
||||
|
@ -791,7 +775,7 @@ namespace SceneUtil
|
|||
|
||||
static bool hasLoggedWarnings = false;
|
||||
|
||||
if (getLightingMethod() == LightingMethod::SingleUBO && !hasLoggedWarnings)
|
||||
if (lightingMethod == LightingMethod::SingleUBO && !hasLoggedWarnings)
|
||||
{
|
||||
if (!supportsUBO)
|
||||
Log(Debug::Warning) << "GL_ARB_uniform_buffer_object not supported: switching to shader compatibility lighting mode";
|
||||
|
@ -802,19 +786,13 @@ namespace SceneUtil
|
|||
|
||||
int targetLights = Settings::Manager::getInt("max lights", "Shaders");
|
||||
|
||||
if (!supportsUBO || !supportsGPU4 || getLightingMethod() == LightingMethod::PerObjectUniform)
|
||||
{
|
||||
setLightingMethod(LightingMethod::PerObjectUniform);
|
||||
if (!supportsUBO || !supportsGPU4 || lightingMethod == LightingMethod::PerObjectUniform)
|
||||
initPerObjectUniform(targetLights);
|
||||
}
|
||||
else
|
||||
{
|
||||
initSingleUBO(targetLights);
|
||||
}
|
||||
|
||||
getOrCreateStateSet()->addUniform(new osg::Uniform("PointLightCount", 0));
|
||||
|
||||
setUpdateCallback(new LightManagerUpdateCallback);
|
||||
addCullCallback(new LightManagerCullCallback(this));
|
||||
}
|
||||
|
||||
|
@ -876,18 +854,18 @@ namespace SceneUtil
|
|||
|
||||
void LightManager::initFFP(int targetLights)
|
||||
{
|
||||
setLightingMethod(LightingMethod::FFP);
|
||||
setMaxLights(targetLights);
|
||||
|
||||
for (int i = 0; i < getMaxLights(); ++i)
|
||||
mDummies.push_back(new FFPLightStateAttribute(i, std::vector<osg::ref_ptr<osg::Light>>()));
|
||||
|
||||
setUpdateCallback(new LightManagerUpdateCallback);
|
||||
}
|
||||
|
||||
void LightManager::initPerObjectUniform(int targetLights)
|
||||
{
|
||||
auto* stateset = getOrCreateStateSet();
|
||||
|
||||
setLightingMethod(LightingMethod::PerObjectUniform);
|
||||
setMaxLights(std::max(2, targetLights));
|
||||
|
||||
mLightUniforms.resize(getMaxLights()+1);
|
||||
|
@ -918,6 +896,7 @@ namespace SceneUtil
|
|||
|
||||
void LightManager::initSingleUBO(int targetLights)
|
||||
{
|
||||
setLightingMethod(LightingMethod::SingleUBO);
|
||||
setMaxLights(std::clamp(targetLights, 2, getMaxLightsInScene() / 2));
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
|
@ -1059,6 +1038,7 @@ namespace SceneUtil
|
|||
|
||||
const std::vector<LightManager::LightSourceViewBound>& LightManager::getLightsInViewSpace(osg::Camera *camera, const osg::RefMatrix* viewMatrix, size_t frameNum)
|
||||
{
|
||||
bool isReflectionCamera = camera->getName() == "ReflectionCamera";
|
||||
osg::observer_ptr<osg::Camera> camPtr (camera);
|
||||
auto it = mLightsInViewSpace.find(camPtr);
|
||||
|
||||
|
@ -1075,17 +1055,18 @@ namespace SceneUtil
|
|||
osg::BoundingSphere viewBound = osg::BoundingSphere(osg::Vec3f(0,0,0), radius * mPointLightRadiusMultiplier);
|
||||
transformBoundingSphere(worldViewMat, viewBound);
|
||||
|
||||
static const float fadeDelta = mPointLightFadeEnd - mPointLightFadeStart;
|
||||
|
||||
if (mPointLightFadeEnd != 0.f)
|
||||
if (!isReflectionCamera)
|
||||
{
|
||||
float fade = 1 - std::clamp((viewBound.center().length() - mPointLightFadeStart) / fadeDelta, 0.f, 1.f);
|
||||
static const float fadeDelta = mPointLightFadeEnd - mPointLightFadeStart;
|
||||
if (mPointLightFadeEnd != 0.f)
|
||||
{
|
||||
float fade = 1 - std::clamp((viewBound.center().length() - mPointLightFadeStart) / fadeDelta, 0.f, 1.f);
|
||||
if (fade == 0.f)
|
||||
continue;
|
||||
|
||||
if (fade == 0.f)
|
||||
continue;
|
||||
|
||||
auto* light = transform.mLightSource->getLight(frameNum);
|
||||
light->setDiffuse(light->getDiffuse() * fade);
|
||||
auto* light = transform.mLightSource->getLight(frameNum);
|
||||
light->setDiffuse(light->getDiffuse() * fade);
|
||||
}
|
||||
}
|
||||
|
||||
LightSourceViewBound l;
|
||||
|
|
|
@ -160,12 +160,12 @@ Sets the internal handling of light sources.
|
|||
'legacy' is restricted to 8 lights per object and emulates fixed function
|
||||
pipeline compatible lighting.
|
||||
|
||||
'shaders compatibility' removes the light limit via :ref:`max lights` and
|
||||
follows a modifed attenuation formula which can drastically reduce light popping
|
||||
and seams. This mode also enables lighting on groundcover and a configurable
|
||||
light fade. It is recommended to use this with older hardware and a light limit
|
||||
closer to 8. Because of its wide range of compatibility it is set as the
|
||||
default.
|
||||
'shaders compatibility' removes the light limit controllable through :ref:`max
|
||||
lights` and follows a modifed attenuation formula which can drastically reduce
|
||||
light popping and seams. This mode also enables lighting on groundcover and a
|
||||
configurable light fade. It is recommended to use this with older hardware and a
|
||||
light limit closer to 8. Because of its wide range of compatibility it is set as
|
||||
the default.
|
||||
|
||||
'shaders' carries all of the benefits that 'shaders compatibility' does, but
|
||||
uses a modern approach that allows for a higher :ref:`max lights` count with
|
||||
|
@ -174,9 +174,9 @@ this mode when supported and where the GPU is not a bottleneck. On some weaker
|
|||
devices, using this mode along with :ref:`force per pixel lighting` can carry
|
||||
performance penalties.
|
||||
|
||||
Note that when enabled, groundcover lighting is forced to be vertex lighting,
|
||||
Note that when enabled groundcover lighting is forced to be vertex lighting,
|
||||
unless normal maps are provided. This is due to some groundcover mods using the
|
||||
Z-Up Normals technique to avoid some common issues with shading. As a
|
||||
Z-Up normals technique to avoid some common issues with shading. As a
|
||||
consequence, per pixel lighting would give undesirable results.
|
||||
|
||||
This setting has no effect if :ref:`force shaders` is 'false'.
|
||||
|
|
|
@ -451,11 +451,11 @@ radial fog = false
|
|||
# 'force per pixel lighting' is enabled.
|
||||
lighting method = shaders compatibility
|
||||
|
||||
# Sets the bounding sphere multiplier of light sources, which are used to
|
||||
# determine if an object should receive 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. It is recommended to keep this
|
||||
# at 1.0 with 'legacy' lighting enabled.
|
||||
# Sets the bounding sphere multiplier of light sources if 'lighting method' is
|
||||
# not 'legacy'. These are used to determine if an object should receive
|
||||
# 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
|
||||
|
||||
# The distance from the camera at which lights fade away completely.
|
||||
|
@ -470,7 +470,7 @@ light fade start = 0.85
|
|||
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.
|
||||
# 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
|
||||
|
||||
|
|
Loading…
Reference in a new issue