From 066185fbcf84e696a957336d48572275abbedba6 Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Sat, 30 Jul 2022 14:37:49 -0700 Subject: [PATCH] override depth write flag from object paging in transparent post-pass --- apps/openmw/mwrender/animation.cpp | 19 ++++++++++++ apps/openmw/mwrender/transparentpass.cpp | 39 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 0933bf4e9e..9d910c00f9 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -51,6 +51,22 @@ namespace { + class MarkDrawablesVisitor : public osg::NodeVisitor + { + public: + MarkDrawablesVisitor(osg::Node::NodeMask mask) + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + , mMask(mask) + { } + + void apply(osg::Drawable& drawable) override + { + drawable.setNodeMask(mMask); + } + + private: + osg::Node::NodeMask mMask = 0; + }; /// Removes all particle systems and related nodes in a subgraph. class RemoveParticlesVisitor : public osg::NodeVisitor @@ -1555,6 +1571,9 @@ namespace MWRender node->setNodeMask(Mask_Effect); + MarkDrawablesVisitor markVisitor(Mask_Effect); + node->accept(markVisitor); + params.mMaxControllerLength = findMaxLengthVisitor.getMaxLength(); params.mLoop = loop; params.mEffectId = effectId; diff --git a/apps/openmw/mwrender/transparentpass.cpp b/apps/openmw/mwrender/transparentpass.cpp index 239a11821b..facd271643 100644 --- a/apps/openmw/mwrender/transparentpass.cpp +++ b/apps/openmw/mwrender/transparentpass.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include @@ -10,6 +12,8 @@ #include #include +#include "vismask.hpp" + namespace MWRender { TransparentDepthBinCallback::TransparentDepthBinCallback(Shader::ShaderManager& shaderManager, bool postPass) @@ -34,6 +38,7 @@ namespace MWRender mStateSet->setAttributeAndModes(new osg::BlendFunc, modeOff); mStateSet->setAttributeAndModes(shaderManager.getProgram(vertex, fragment), modeOn); + mStateSet->setAttributeAndModes(new SceneUtil::AutoDepth, modeOn); for (unsigned int unit = 1; unit < 8; ++unit) mStateSet->setTextureMode(unit, GL_TEXTURE_2D, modeOff); @@ -88,11 +93,35 @@ namespace MWRender opaqueFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); - osg::ref_ptr restore = bin->getStateSet(); - bin->setStateSet(mStateSet); - // draws transparent post-pass to populate a postprocess friendly depth texture with alpha-clipped geometry - bin->drawImplementation(renderInfo, previous); - bin->setStateSet(restore); + // draw transparent post-pass to populate a postprocess friendly depth texture with alpha-clipped geometry + + unsigned int numToPop = previous ? osgUtil::StateGraph::numToPop(previous->_parent) : 0; + if (numToPop > 1) + numToPop--; + unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop; + + state.insertStateSet(insertStateSetPosition, mStateSet); + for(auto rit = bin->getRenderLeafList().begin(); rit != bin->getRenderLeafList().end(); rit++) + { + osgUtil::RenderLeaf* rl = *rit; + const osg::StateSet* ss = rl->_parent->getStateSet(); + + if (rl->_drawable->getNodeMask() == Mask_ParticleSystem || rl->_drawable->getNodeMask() == Mask_Effect) + continue; + + if (ss->getAttribute(osg::StateAttribute::ALPHAFUNC)) + continue; + + if (ss->getAttribute(osg::StateAttribute::MATERIAL)) { + const osg::Material* mat = static_cast(ss->getAttribute(osg::StateAttribute::MATERIAL)); + if (mat->getDiffuse(osg::Material::FRONT).a() < 0.5) + continue; + } + + rl->render(renderInfo,previous); + previous = rl; + } + state.removeStateSet(insertStateSetPosition); msaaFbo ? msaaFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER) : fbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); state.checkGLErrors("after TransparentDepthBinCallback::drawImplementation");