From 8af8ad38406c35182dcb23a3c511be007a87dd9c Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 20 Jan 2021 01:17:16 +0000 Subject: [PATCH] Always write opaque fragments instead of relying on blending being off for translucent RTT --- apps/openmw/mwrender/characterpreview.cpp | 26 +++++++++++++++++++++-- apps/openmw/mwrender/renderingmanager.cpp | 1 + files/shaders/objects_fragment.glsl | 4 ++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 89db3e5f46..f21e667eb0 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -85,7 +86,7 @@ namespace MWRender class SetUpBlendVisitor : public osg::NodeVisitor { public: - SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mNoAlphaUniform(new osg::Uniform("noAlpha", false)) { } @@ -102,10 +103,17 @@ namespace MWRender newStateSet->setAttribute(newBlendFunc, osg::StateAttribute::ON); node.setStateSet(newStateSet); } - + if (stateset->getMode(GL_BLEND) & osg::StateAttribute::ON) + { + // Disable noBlendAlphaEnv + stateset->setTextureMode(7, GL_TEXTURE_2D, osg::StateAttribute::OFF); + stateset->addUniform(mNoAlphaUniform); + } } traverse(node); } + private: + osg::ref_ptr mNoAlphaUniform; }; CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, @@ -164,6 +172,20 @@ namespace MWRender fog->setEnd(10000000); stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE); + // Opaque stuff must have 1 as its fragment alpha as the FBO is translucent, so having blending off isn't enough + osg::ref_ptr noBlendAlphaEnv = new osg::TexEnvCombine(); + noBlendAlphaEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE); + noBlendAlphaEnv->setSource0_Alpha(osg::TexEnvCombine::CONSTANT); + noBlendAlphaEnv->setConstantColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); + noBlendAlphaEnv->setCombine_RGB(osg::TexEnvCombine::REPLACE); + noBlendAlphaEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); + osg::ref_ptr dummyTexture = new osg::Texture2D(); + dummyTexture->setInternalFormat(GL_RED); + dummyTexture->setTextureSize(1, 1); + stateset->setTextureAttributeAndModes(7, dummyTexture, osg::StateAttribute::ON); + stateset->setTextureAttribute(7, noBlendAlphaEnv, osg::StateAttribute::ON); + stateset->addUniform(new osg::Uniform("noAlpha", true)); + osg::ref_ptr lightmodel = new osg::LightModel; lightmodel->setAmbientIntensity(osg::Vec4(0.0, 0.0, 0.0, 1.0)); stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6ce431d2e2..e1f6f0dd96 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -370,6 +370,7 @@ namespace MWRender mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("near", mNearClip)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("far", mViewDistance)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("simpleWater", false)); + mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("noAlpha", false)); mUniformNear = mRootNode->getOrCreateStateSet()->getUniform("near"); mUniformFar = mRootNode->getOrCreateStateSet()->getUniform("far"); diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index 78660685f6..bd2bd5909f 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -50,6 +50,7 @@ uniform mat2 bumpMapMatrix; #endif uniform bool simpleWater; +uniform bool noAlpha; varying float euclideanDepth; varying float linearDepth; @@ -208,5 +209,8 @@ void main() #endif gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue); + if (noAlpha) + gl_FragData[0].a = 1.0; + applyShadowDebugOverlay(); }