From 33e39a03604ea15310860a0b5893a75b7eb27e7d 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 | 1 + 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, 51 insertions(+), 2 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index e6dd74dbd7..c4bce8a968 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -127,6 +127,7 @@ bool Launcher::AdvancedPage::loadSettings() if (Settings::Manager::getInt("antialiasing", "Video") == 0) { antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked); } + loadSettingBool(adjustCoverageForAlphaTestCheckBox, "adjust coverage for alpha test", "Shaders"); loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool))); loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); @@ -281,6 +282,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 5a88afd78b..7e9d1c0866 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -412,6 +412,7 @@ namespace MWRender resourceSystem->getSceneManager()->setSpecularMapPattern(Settings::Manager::getString("specular map pattern", "Shaders")); 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); + 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. osg::ref_ptr sceneRoot = new SceneUtil::LightManager(lightingMethod == SceneUtil::LightingMethod::FFP); diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 738505b2d6..122dbd92d1 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -346,6 +346,7 @@ namespace Resource , mApplyLightingToEnvMaps(false) , mLightingMethod(SceneUtil::LightingMethod::FFP) , mConvertAlphaTestToAlphaToCoverage(false) + , mAdjustCoverageForAlphaTest(false) , mSupportsNormalsRT(false) , mSharedStateManager(new SharedStateManager) , mImageManager(imageManager) @@ -456,6 +457,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 }; @@ -1046,6 +1052,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 d3ad868a99..05ddd2eee1 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -123,6 +123,7 @@ namespace Resource SceneUtil::LightingMethod getLightingMethod() const; void setConvertAlphaTestToAlphaToCoverage(bool convert); + void setAdjustCoverageForAlphaTest(bool adjustCoverage); void setShaderPath(const std::string& path); @@ -217,6 +218,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 08f6894f71..7a949aac80 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -170,6 +170,7 @@ namespace Shader , mAutoUseSpecularMaps(false) , mApplyLightingToEnvMaps(false) , mConvertAlphaTestToAlphaToCoverage(false) + , mAdjustCoverageForAlphaTest(false) , mSupportsNormalsRT(false) , mShaderManager(shaderManager) , mImageManager(imageManager) @@ -614,7 +615,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 @@ -929,6 +930,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 02323f528f..dbe5f4f776 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 779739eae5..08f3fb0fa0 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -487,6 +487,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 6a50fc8a9b..b1753900aa 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -455,7 +455,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> @@ -465,6 +465,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 + + +