From 52a16e0e9300e9bf22a2630eb150cd2da0ba941e Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 9 Jul 2023 02:28:36 +0300 Subject: [PATCH] BSEffectShader/NoLighting fixes Don't hijack BSShader::NoLighting for BSEffectShader functionality (Fallout meshes break if you use the actual emissive color as a base color) Don't use falloff for textureless NoLighting objects Use falloff flag for BSEffectShader --- components/nif/property.hpp | 2 ++ components/nifosg/nifloader.cpp | 35 +++++++------------ .../shaders/compatibility/bs/nolighting.frag | 5 --- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 3e45c83ad6..bd80d64712 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -232,6 +232,8 @@ namespace Nif std::string mGreyscaleTexture; void read(NIFStream* nif) override; + + bool useFalloff() const { return (flags >> 6) & 1; } }; struct NiDitherProperty : public Property diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 84aaf8ca05..98cc25f90d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -2177,6 +2177,7 @@ namespace NifOsg { auto texprop = static_cast(property); bool shaderRequired = true; + bool useFalloff = false; node->setUserValue("shaderPrefix", std::string(getBSShaderPrefix(texprop->type))); node->setUserValue("shaderRequired", shaderRequired); osg::StateSet* stateset = node->getOrCreateStateSet(); @@ -2200,16 +2201,13 @@ namespace NifOsg const unsigned int uvSet = 0; stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON); boundTextures.push_back(uvSet); + if (mBethVersion >= 27) + { + useFalloff = true; + stateset->addUniform(new osg::Uniform("falloffParams", texprop->falloffParams)); + } } - if (mBethVersion >= 27) - { - stateset->addUniform(new osg::Uniform("useFalloff", true)); - stateset->addUniform(new osg::Uniform("falloffParams", texprop->falloffParams)); - } - else - { - stateset->addUniform(new osg::Uniform("useFalloff", false)); - } + stateset->addUniform(new osg::Uniform("useFalloff", useFalloff)); handleTextureControllers(texprop, composite, imageManager, stateset, animflags); if (texprop->doubleSided()) stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); @@ -2236,6 +2234,7 @@ namespace NifOsg { auto texprop = static_cast(property); bool shaderRequired = true; + // TODO: implement BSEffectShader as a shader node->setUserValue("shaderPrefix", std::string("bs/nolighting")); node->setUserValue("shaderRequired", shaderRequired); osg::StateSet* stateset = node->getOrCreateStateSet(); @@ -2277,8 +2276,10 @@ namespace NifOsg stateset->setTextureAttributeAndModes(texUnit, texMat, osg::StateAttribute::ON); } } - stateset->addUniform(new osg::Uniform("useFalloff", false)); // Should use the shader flag - stateset->addUniform(new osg::Uniform("falloffParams", texprop->mFalloffParams)); + bool useFalloff = texprop->useFalloff(); + stateset->addUniform(new osg::Uniform("useFalloff", useFalloff)); + if (useFalloff) + stateset->addUniform(new osg::Uniform("falloffParams", texprop->mFalloffParams)); handleTextureControllers(texprop, composite, imageManager, stateset, animflags); if (texprop->doubleSided()) stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); @@ -2469,11 +2470,6 @@ namespace NifOsg } break; } - case Nif::RC_BSShaderNoLightingProperty: - { - mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.f, 1.f, 1.f, 1.f)); - break; - } case Nif::RC_BSLightingShaderProperty: { auto shaderprop = static_cast(property); @@ -2485,13 +2481,6 @@ namespace NifOsg specStrength = shaderprop->mSpecStrength; break; } - case Nif::RC_BSEffectShaderProperty: - { - auto shaderprop = static_cast(property); - mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(shaderprop->mBaseColor)); - emissiveMult = shaderprop->mBaseColorScale; - break; - } default: break; } diff --git a/files/shaders/compatibility/bs/nolighting.frag b/files/shaders/compatibility/bs/nolighting.frag index 9572088876..4a5c1c3b42 100644 --- a/files/shaders/compatibility/bs/nolighting.frag +++ b/files/shaders/compatibility/bs/nolighting.frag @@ -21,7 +21,6 @@ varying float passFalloff; uniform vec2 screenRes; uniform bool useFalloff; -uniform float emissiveMult; uniform float far; uniform float alphaRef; @@ -45,10 +44,6 @@ void main() if (useFalloff) gl_FragData[0].a *= passFalloff; - vec4 emissionColor = getEmissionColor(); - gl_FragData[0].rgb *= emissionColor.rgb * emissiveMult; - gl_FragData[0].a *= emissionColor.a * emissionColor.a; // sic - gl_FragData[0].a = alphaTest(gl_FragData[0].a, alphaRef); gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, far);