From 66b8d4fb291eb8d7144ae78b77f39978151eb36e Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 9 Dec 2022 00:22:08 +0000 Subject: [PATCH] Add a setting to control coverage adjustment With it on, which was always the case before this setting was added, vanilla content and poorly-made mods will look acceptable, but well-made mods will have alpha-tested meshes appear to grow and potentially gain a weird outline as they get further away. With it off, which replicates the 0.46 behaviour, well-made mods will look really good, but vanilla content and poorly-made mods will have alpha-tested meshes shrink as they get further away. It's been bugging me that this was forced on since 0.47 released, and I'd hoped to figure out a solution for automatic detection at some point before 0.48 branched off, but I didn't, so now this is what we're getting to have Tamriel Rebuilt look right. --- apps/launcher/advancedpage.cpp | 2 ++ apps/openmw/mwrender/renderingmanager.cpp | 2 ++ components/resource/scenemanager.cpp | 7 +++++++ components/resource/scenemanager.hpp | 2 ++ components/shader/shadervisitor.cpp | 8 +++++++- components/shader/shadervisitor.hpp | 2 ++ docs/source/reference/modding/settings/shaders.rst | 13 +++++++++++++ files/settings-default.cfg | 6 ++++++ files/ui/advancedpage.ui | 12 +++++++++++- 9 files changed, 52 insertions(+), 2 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 79530855bb..9293ffa307 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -126,6 +126,7 @@ bool Launcher::AdvancedPage::loadSettings() { antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked); } + loadSettingBool(adjustCoverageForAlphaTestCheckBox, "adjust coverage for alpha test", "Shaders"); loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); connect(animSourcesCheckBox, &QCheckBox::toggled, this, &AdvancedPage::slotAnimSourcesToggled); loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); @@ -285,6 +286,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(radialFogCheckBox, "radial fog", "Fog"); saveSettingBool(softParticlesCheckBox, "soft particles", "Shaders"); saveSettingBool(antialiasAlphaTestCheckBox, "antialias alpha test", "Shaders"); + saveSettingBool(adjustCoverageForAlphaTestCheckBox, "adjust coverage for alpha test", "Shaders"); saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0262adad39..cb5ad8d9a6 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -388,6 +388,8 @@ namespace MWRender resourceSystem->getSceneManager()->setConvertAlphaTestToAlphaToCoverage( Settings::Manager::getBool("antialias alpha test", "Shaders") && Settings::Manager::getInt("antialiasing", "Video") > 1); + resourceSystem->getSceneManager()->setAdjustCoverageForAlphaTest( + Settings::Manager::getBool("adjust coverage for alpha test", "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. diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 037da7be4c..06fbd8470f 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -361,6 +361,7 @@ namespace Resource , mApplyLightingToEnvMaps(false) , mLightingMethod(SceneUtil::LightingMethod::FFP) , mConvertAlphaTestToAlphaToCoverage(false) + , mAdjustCoverageForAlphaTest(false) , mSupportsNormalsRT(false) , mSharedStateManager(new SharedStateManager) , mImageManager(imageManager) @@ -473,6 +474,11 @@ namespace Resource mConvertAlphaTestToAlphaToCoverage = convert; } + void SceneManager::setAdjustCoverageForAlphaTest(bool adjustCoverage) + { + mAdjustCoverageForAlphaTest = adjustCoverage; + } + void SceneManager::setOpaqueDepthTex(osg::ref_ptr texturePing, osg::ref_ptr texturePong) { mOpaqueDepthTex = { texturePing, texturePong }; @@ -1099,6 +1105,7 @@ namespace Resource shaderVisitor->setSpecularMapPattern(mSpecularMapPattern); shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps); shaderVisitor->setConvertAlphaTestToAlphaToCoverage(mConvertAlphaTestToAlphaToCoverage); + shaderVisitor->setAdjustCoverageForAlphaTest(mAdjustCoverageForAlphaTest); shaderVisitor->setSupportsNormalsRT(mSupportsNormalsRT); return shaderVisitor; } diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index ac0040f9db..9b77e742df 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -145,6 +145,7 @@ namespace Resource SceneUtil::LightingMethod getLightingMethod() const; void setConvertAlphaTestToAlphaToCoverage(bool convert); + void setAdjustCoverageForAlphaTest(bool adjustCoverage); void setShaderPath(const std::filesystem::path& path); @@ -240,6 +241,7 @@ namespace Resource SceneUtil::LightingMethod mLightingMethod; SceneUtil::LightManager::SupportedMethods mSupportedLightingMethods; bool mConvertAlphaTestToAlphaToCoverage; + bool mAdjustCoverageForAlphaTest; bool mSupportsNormalsRT; std::array, 2> mOpaqueDepthTex; bool mSoftParticles = false; diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index f79792bf2b..4e5f68edf5 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -196,6 +196,7 @@ namespace Shader , mAutoUseSpecularMaps(false) , mApplyLightingToEnvMaps(false) , mConvertAlphaTestToAlphaToCoverage(false) + , mAdjustCoverageForAlphaTest(false) , mSupportsNormalsRT(false) , mShaderManager(shaderManager) , mImageManager(imageManager) @@ -656,7 +657,7 @@ namespace Shader // Adjusting coverage isn't safe with blending on as blending requires the alpha to be intact. // Maybe we could also somehow (e.g. userdata) detect when the diffuse map has coverage-preserving mip maps // in the future - if (!reqs.mAlphaBlend) + if (mAdjustCoverageForAlphaTest && !reqs.mAlphaBlend) defineMap["adjustCoverage"] = "1"; // Preventing alpha tested stuff shrinking as lower mip levels are used requires knowing the texture size @@ -977,6 +978,11 @@ namespace Shader mConvertAlphaTestToAlphaToCoverage = convert; } + void ShaderVisitor::setAdjustCoverageForAlphaTest(bool adjustCoverage) + { + mAdjustCoverageForAlphaTest = adjustCoverage; + } + ReinstateRemovedStateVisitor::ReinstateRemovedStateVisitor(bool allowedToModifyStateSets) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mAllowedToModifyStateSets(allowedToModifyStateSets) diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 8b6fa4941c..0bd8bb9cd7 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -47,6 +47,7 @@ namespace Shader void setApplyLightingToEnvMaps(bool apply); void setConvertAlphaTestToAlphaToCoverage(bool convert); + void setAdjustCoverageForAlphaTest(bool adjustCoverage); void setSupportsNormalsRT(bool supports) { mSupportsNormalsRT = supports; } @@ -74,6 +75,7 @@ namespace Shader bool mApplyLightingToEnvMaps; bool mConvertAlphaTestToAlphaToCoverage; + bool mAdjustCoverageForAlphaTest; bool mSupportsNormalsRT; diff --git a/docs/source/reference/modding/settings/shaders.rst b/docs/source/reference/modding/settings/shaders.rst index 10752d8ba4..bd74d01fdd 100644 --- a/docs/source/reference/modding/settings/shaders.rst +++ b/docs/source/reference/modding/settings/shaders.rst @@ -259,6 +259,19 @@ Convert the alpha test (cutout/punchthrough alpha) to alpha-to-coverage when :re This allows MSAA to work with alpha-tested meshes, producing better-looking edges without pixelation. When MSAA is off, this setting will have no visible effect, but might have a performance cost. + +adjust coverage for alpha test +------------------------------ + +:Type: boolean +:Range: True/False +:Default: True + +Attempt to simulate coverage-preserving mipmaps in textures created without them which are used for alpha testing anyway. +This will somewhat mitigate these objects appearing to shrink as they get further from the camera, but isn't perfect. +Better results can be achieved by generating more appropriate mipmaps in the first place, but if this workaround is used with such textures, affected objects will appear to grow as they get further from the camera. +It is recommended that mod authors specify how this setting should be set, and mod users follow their advice. + soft particles -------------- diff --git a/files/settings-default.cfg b/files/settings-default.cfg index c477187321..33b1dd89d1 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -490,6 +490,12 @@ minimum interior brightness = 0.08 # When MSAA is off, this setting will have no visible effect, but might have a performance cost. antialias alpha test = false +# Attempt to simulate coverage-preserving mipmaps in textures created without them which are used for alpha testing anyway. +# This will somewhat mitigate these objects appearing to shrink as they get further from the camera, but isn't perfect. +# Better results can be achieved by generating more appropriate mipmaps in the first place, but if this workaround is used with such textures, affected objects will appear to grow as they get further from the camera. +# It is recommended that mod authors specify how this setting should be set, and mod users follow their advice. +adjust coverage for alpha test = true + # Soften intersection of blended particle systems with opaque geometry soft particles = false diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 47c17aca03..5766910f2e 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -465,7 +465,7 @@ - + <html><head/><body><p>Enables soft particles for particle effects. This technique softens the intersection between individual particles and other opaque geometry by blending between them.</p></body></html> @@ -475,6 +475,16 @@ + + + + <html><head/><body><p>Simulate coverage-preserving mipmaps to prevent alpha-tested meshes shrinking as they get further away. Will cause meshes whose textures have coverage-preserving mipmaps to grow, though, so refer to mod installation instructions for how to set this.</p></body></html> + + + Adjust coverage for alpha test + + +