From 72f7e6a702cef495159869e3bde2de1d4627c7b8 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 12 Nov 2020 00:26:30 +0000 Subject: [PATCH] Handle all shadow alpha uniforms in shadowsbin --- apps/openmw/mwrender/animation.cpp | 12 ++------ components/sceneutil/mwshadowtechnique.cpp | 11 +------- components/sceneutil/mwshadowtechnique.hpp | 1 - components/sceneutil/shadowsbin.cpp | 33 ++++++++++++++-------- components/sceneutil/shadowsbin.hpp | 7 +++-- components/shader/shadermanager.cpp | 10 ------- components/shader/shadermanager.hpp | 6 ---- components/shader/shadervisitor.cpp | 28 +----------------- components/shader/shadervisitor.hpp | 1 - 9 files changed, 29 insertions(+), 80 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 29645a7c19..94a5219601 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include @@ -37,8 +36,6 @@ #include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" @@ -493,9 +490,8 @@ namespace MWRender class TransparencyUpdater : public SceneUtil::StateSetUpdater { public: - TransparencyUpdater(const float alpha, osg::ref_ptr shadowUniform) + TransparencyUpdater(const float alpha) : mAlpha(alpha) - , mShadowUniform(shadowUniform) { } @@ -509,9 +505,6 @@ namespace MWRender { osg::BlendFunc* blendfunc (new osg::BlendFunc); stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - // TODO: don't do this anymore once custom shadow renderbin is handling it - if (mShadowUniform) - stateset->addUniform(mShadowUniform); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); @@ -533,7 +526,6 @@ namespace MWRender private: float mAlpha; - osg::ref_ptr mShadowUniform; }; struct Animation::AnimSource @@ -1773,7 +1765,7 @@ namespace MWRender { if (mTransparencyUpdater == nullptr) { - mTransparencyUpdater = new TransparencyUpdater(alpha, mResourceSystem->getSceneManager()->getShaderManager().getShadowMapAlphaTestEnableUniform()); + mTransparencyUpdater = new TransparencyUpdater(alpha); mObjectRoot->addCullCallback(mTransparencyUpdater); } else diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index c8a241c36a..06a1efd2a6 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -885,15 +885,6 @@ void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & sh _castingProgram->addShader(shaderManager.getShader("shadowcasting_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::VERTEX)); _castingProgram->addShader(shaderManager.getShader("shadowcasting_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::FRAGMENT)); - - _shadowMapAlphaTestDisableUniform = shaderManager.getShadowMapAlphaTestDisableUniform(); - _shadowMapAlphaTestDisableUniform->setName("alphaTestShadows"); - _shadowMapAlphaTestDisableUniform->setType(osg::Uniform::BOOL); - _shadowMapAlphaTestDisableUniform->set(false); - - shaderManager.getShadowMapAlphaTestEnableUniform()->setName("alphaTestShadows"); - shaderManager.getShadowMapAlphaTestEnableUniform()->setType(osg::Uniform::BOOL); - shaderManager.getShadowMapAlphaTestEnableUniform()->set(true); } MWShadowTechnique::ViewDependentData* MWShadowTechnique::createViewDependentData(osgUtil::CullVisitor* /*cv*/) @@ -1595,7 +1586,7 @@ void MWShadowTechnique::createShaders() // The casting program uses a sampler, so to avoid undefined behaviour, we must bind a dummy texture in case no other is supplied _shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); - _shadowCastingStateSet->addUniform(_shadowMapAlphaTestDisableUniform); + _shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); osg::ref_ptr depth = new osg::Depth; depth->setWriteMask(true); _shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 23a8e009a5..a7208cfa6d 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -288,7 +288,6 @@ namespace SceneUtil { osg::ref_ptr _debugHud; osg::ref_ptr _castingProgram; - osg::ref_ptr _shadowMapAlphaTestDisableUniform; }; } diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp index e0a141ffb4..4c0c78cabd 100644 --- a/components/sceneutil/shadowsbin.cpp +++ b/components/sceneutil/shadowsbin.cpp @@ -42,11 +42,16 @@ namespace SceneUtil ShadowsBin::ShadowsBin() { - mStateSet = new osg::StateSet; - mStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); + mNoTestStateSet = new osg::StateSet; + mNoTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); + mNoTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); + + mShaderAlphaTestStateSet = new osg::StateSet; + mShaderAlphaTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", true)); + mShaderAlphaTestStateSet->setMode(GL_BLEND, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); } -bool ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered_set& uninterestingCache) +StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered_set& uninterestingCache) { std::vector return_path; State state; @@ -88,7 +93,7 @@ bool ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered } if (!state.needShadows()) - return true; + return nullptr; if (!state.needTexture() && !state.mImportantState) { @@ -97,9 +102,12 @@ bool ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered leaf->_parent = root; root->_leaves.push_back(leaf); } - return true; + return nullptr; } - return false; + + if (state.mAlphaBlend) + return sg->find_or_insert(mShaderAlphaTestStateSet); + return sg; } bool ShadowsBin::State::needShadows() const @@ -128,9 +136,9 @@ void ShadowsBin::sortImplementation() if (!root->_parent) return; } - root = root->find_or_insert(mStateSet.get()); + StateGraph* noTestRoot = root->find_or_insert(mNoTestStateSet.get()); // root is now a stategraph with useDiffuseMapForShadowAlpha disabled but minimal other state - root->_leaves.reserve(_stateGraphList.size()); + noTestRoot->_leaves.reserve(_stateGraphList.size()); StateGraphList newList; std::unordered_set uninterestingCache; for (StateGraph* graph : _stateGraphList) @@ -138,11 +146,12 @@ void ShadowsBin::sortImplementation() // Render leaves which shouldn't use the diffuse map for shadow alpha but do cast shadows become children of root, so graph is now empty. Don't add to newList. // Graphs containing just render leaves which don't cast shadows are discarded. Don't add to newList. // Graphs containing other leaves need to be in newList. - if (!cullStateGraph(graph, root, uninterestingCache)) - newList.push_back(graph); + StateGraph* graphToAdd = cullStateGraph(graph, noTestRoot, uninterestingCache); + if (graphToAdd) + newList.push_back(graphToAdd); } - if (!root->_leaves.empty()) - newList.push_back(root); + if (!noTestRoot->_leaves.empty()) + newList.push_back(noTestRoot); _stateGraphList = newList; } diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp index 6c35e17794..13f68ec90f 100644 --- a/components/sceneutil/shadowsbin.hpp +++ b/components/sceneutil/shadowsbin.hpp @@ -15,11 +15,12 @@ namespace SceneUtil class ShadowsBin : public osgUtil::RenderBin { private: - osg::ref_ptr mStateSet; + osg::ref_ptr mNoTestStateSet; + osg::ref_ptr mShaderAlphaTestStateSet; public: META_Object(SceneUtil, ShadowsBin) ShadowsBin(); - ShadowsBin(const ShadowsBin& rhs, const osg::CopyOp& copyop) : osgUtil::RenderBin(rhs, copyop), mStateSet(rhs.mStateSet) {} + ShadowsBin(const ShadowsBin& rhs, const osg::CopyOp& copyop) : osgUtil::RenderBin(rhs, copyop), mNoTestStateSet(rhs.mNoTestStateSet), mShaderAlphaTestStateSet(rhs.mShaderAlphaTestStateSet) {} void sortImplementation() override; @@ -39,7 +40,7 @@ namespace SceneUtil bool interesting() const { return !needShadows() || needTexture() || mAlphaBlendOverride || mAlphaTestOverride || mMaterialOverride || mImportantState; } }; - bool cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting); + osgUtil::StateGraph* cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting); static void addPrototype(const std::string& name) { diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index bfaa112825..788a8720bc 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -384,14 +384,4 @@ namespace Shader program.second->releaseGLObjects(state); } - const osg::ref_ptr ShaderManager::getShadowMapAlphaTestEnableUniform() - { - return mShadowMapAlphaTestEnableUniform; - } - - const osg::ref_ptr ShaderManager::getShadowMapAlphaTestDisableUniform() - { - return mShadowMapAlphaTestDisableUniform; - } - } diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index ed5bbc907b..13db30b019 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -43,9 +43,6 @@ namespace Shader void releaseGLObjects(osg::State* state); - const osg::ref_ptr getShadowMapAlphaTestEnableUniform(); - const osg::ref_ptr getShadowMapAlphaTestDisableUniform(); - private: std::string mPath; @@ -63,9 +60,6 @@ namespace Shader ProgramMap mPrograms; std::mutex mMutex; - - const osg::ref_ptr mShadowMapAlphaTestEnableUniform = new osg::Uniform(); - const osg::ref_ptr mShadowMapAlphaTestDisableUniform = new osg::Uniform(); }; bool parseFors(std::string& source, const std::string& templateName); diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index c30307f29d..f17c4a80c1 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -1,7 +1,5 @@ #include "shadervisitor.hpp" -#include -#include #include #include #include @@ -25,7 +23,6 @@ namespace Shader : mShaderRequired(false) , mColorMode(0) , mMaterialOverridden(false) - , mBlendFuncOverridden(false) , mNormalHeight(false) , mTexStageRequiringTangents(-1) , mNode(nullptr) @@ -233,14 +230,11 @@ namespace Shader if (!writableStateSet) writableStateSet = getWritableStateSet(node); // We probably shouldn't construct a new version of this each time as Uniforms use pointer comparison for early-out. - // Also it should probably belong to the shader manager + // Also it should probably belong to the shader manager or be applied by the shadows bin writableStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); } } - bool alphaSettingsChanged = false; - bool alphaTestShadows = false; - const osg::StateSet::AttributeList& attributes = stateset->getAttributeList(); for (osg::StateSet::AttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { @@ -284,28 +278,8 @@ namespace Shader mRequirements.back().mColorMode = colorMode; } } - else if (it->first.first == osg::StateAttribute::BLENDFUNC) - { - if (!mRequirements.back().mBlendFuncOverridden || it->second.second & osg::StateAttribute::PROTECTED) - { - if (it->second.second & osg::StateAttribute::OVERRIDE) - mRequirements.back().mBlendFuncOverridden = true; - - const osg::BlendFunc* blend = static_cast(it->second.first.get()); - if (blend->getSource() == osg::BlendFunc::SRC_ALPHA || blend->getSource() == osg::BlendFunc::SRC_COLOR) - alphaTestShadows = true; - alphaSettingsChanged = true; - } - } // Eventually, move alpha testing to discard in shader adn remove deprecated state here } - // we don't need to check for glEnable/glDisable of blending as we always set it at the same time - if (alphaSettingsChanged) - { - if (!writableStateSet) - writableStateSet = getWritableStateSet(node); - writableStateSet->addUniform(alphaTestShadows ? mShaderManager.getShadowMapAlphaTestEnableUniform() : mShaderManager.getShadowMapAlphaTestDisableUniform()); - } } void ShaderVisitor::pushRequirements(osg::Node& node) diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index bf10221801..ae157b9764 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -75,7 +75,6 @@ namespace Shader int mColorMode; bool mMaterialOverridden; - bool mBlendFuncOverridden; bool mNormalHeight; // true if normal map has height info in alpha channel