mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-06 09:39:49 +00:00
Apply soft effect to nifs marked with soft effect flag (developed by Cody Glassman)
This commit is contained in:
parent
c302b45777
commit
63d5bd6f8a
@ -232,6 +232,7 @@ namespace Nif
|
|||||||
enum BSLightingShaderFlags1
|
enum BSLightingShaderFlags1
|
||||||
{
|
{
|
||||||
BSLSFlag1_Falloff = 0x00000040,
|
BSLSFlag1_Falloff = 0x00000040,
|
||||||
|
BSLSFlag1_SoftEffect = 0x40000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BSLightingShaderFlags2
|
enum BSLightingShaderFlags2
|
||||||
@ -354,6 +355,7 @@ namespace Nif
|
|||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
|
|
||||||
bool useFalloff() const { return mShaderFlags1 & BSLSFlag1_Falloff; }
|
bool useFalloff() const { return mShaderFlags1 & BSLSFlag1_Falloff; }
|
||||||
|
bool softEffect() const { return mShaderFlags1 & BSLSFlag1_SoftEffect; }
|
||||||
bool doubleSided() const { return mShaderFlags2 & BSLSFlag2_DoubleSided; }
|
bool doubleSided() const { return mShaderFlags2 & BSLSFlag2_DoubleSided; }
|
||||||
bool treeAnim() const { return mShaderFlags2 & BSLSFlag2_TreeAnim; }
|
bool treeAnim() const { return mShaderFlags2 & BSLSFlag2_TreeAnim; }
|
||||||
};
|
};
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <components/nif/property.hpp>
|
#include <components/nif/property.hpp>
|
||||||
#include <components/nif/texture.hpp>
|
#include <components/nif/texture.hpp>
|
||||||
#include <components/sceneutil/depth.hpp>
|
#include <components/sceneutil/depth.hpp>
|
||||||
|
#include <components/sceneutil/extradata.hpp>
|
||||||
#include <components/sceneutil/morphgeometry.hpp>
|
#include <components/sceneutil/morphgeometry.hpp>
|
||||||
#include <components/sceneutil/riggeometry.hpp>
|
#include <components/sceneutil/riggeometry.hpp>
|
||||||
#include <components/sceneutil/skeleton.hpp>
|
#include <components/sceneutil/skeleton.hpp>
|
||||||
@ -2561,6 +2562,8 @@ namespace NifOsg
|
|||||||
polygonOffset->setFactor(SceneUtil::AutoDepth::isReversed() ? 0.65f : -0.65f);
|
polygonOffset->setFactor(SceneUtil::AutoDepth::isReversed() ? 0.65f : -0.65f);
|
||||||
stateset->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON);
|
stateset->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
if (shaderprop->softEffect())
|
||||||
|
SceneUtil::setupSoftEffect(*node, shaderprop->mFalloffDepth, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -15,18 +15,12 @@
|
|||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
void ProcessExtraDataVisitor::setupSoftEffect(osg::Node& node, float size, bool falloff)
|
void setupSoftEffect(osg::Node& node, float size, bool falloff)
|
||||||
{
|
{
|
||||||
if (!mSceneMgr->getSoftParticles())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const int unitSoftEffect
|
|
||||||
= mSceneMgr->getShaderManager().reserveGlobalTextureUnits(Shader::ShaderManager::Slot::OpaqueDepthTexture);
|
|
||||||
static const osg::ref_ptr<SceneUtil::AutoDepth> depth = new SceneUtil::AutoDepth(osg::Depth::LESS, 0, 1, false);
|
static const osg::ref_ptr<SceneUtil::AutoDepth> depth = new SceneUtil::AutoDepth(osg::Depth::LESS, 0, 1, false);
|
||||||
|
|
||||||
osg::StateSet* stateset = node.getOrCreateStateSet();
|
osg::StateSet* stateset = node.getOrCreateStateSet();
|
||||||
|
|
||||||
stateset->addUniform(new osg::Uniform("opaqueDepthTex", unitSoftEffect));
|
|
||||||
stateset->addUniform(new osg::Uniform("particleSize", size));
|
stateset->addUniform(new osg::Uniform("particleSize", size));
|
||||||
stateset->addUniform(new osg::Uniform("particleFade", falloff));
|
stateset->addUniform(new osg::Uniform("particleFade", falloff));
|
||||||
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||||
@ -36,6 +30,9 @@ namespace SceneUtil
|
|||||||
|
|
||||||
void ProcessExtraDataVisitor::apply(osg::Node& node)
|
void ProcessExtraDataVisitor::apply(osg::Node& node)
|
||||||
{
|
{
|
||||||
|
if (!mSceneMgr->getSoftParticles())
|
||||||
|
return;
|
||||||
|
|
||||||
std::string source;
|
std::string source;
|
||||||
|
|
||||||
if (node.getUserValue(Misc::OsgUserValues::sExtraData, source) && !source.empty())
|
if (node.getUserValue(Misc::OsgUserValues::sExtraData, source) && !source.empty())
|
||||||
@ -64,4 +61,4 @@ namespace SceneUtil
|
|||||||
|
|
||||||
traverse(node);
|
traverse(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ namespace osg
|
|||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
|
void setupSoftEffect(osg::Node& node, float size, bool falloff);
|
||||||
|
|
||||||
class ProcessExtraDataVisitor : public osg::NodeVisitor
|
class ProcessExtraDataVisitor : public osg::NodeVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -27,8 +29,6 @@ namespace SceneUtil
|
|||||||
void apply(osg::Node& node) override;
|
void apply(osg::Node& node) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupSoftEffect(osg::Node& node, float size, bool falloff);
|
|
||||||
|
|
||||||
Resource::SceneManager* mSceneMgr;
|
Resource::SceneManager* mSceneMgr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -690,6 +690,13 @@ namespace Shader
|
|||||||
writableStateSet->setAttribute(new osg::ColorMaski(1, false, false, false, false));
|
writableStateSet->setAttribute(new osg::ColorMaski(1, false, false, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reqs.mSoftParticles)
|
||||||
|
{
|
||||||
|
const int unitSoftEffect
|
||||||
|
= mShaderManager.reserveGlobalTextureUnits(Shader::ShaderManager::Slot::OpaqueDepthTexture);
|
||||||
|
writableStateSet->addUniform(new osg::Uniform("opaqueDepthTex", unitSoftEffect));
|
||||||
|
}
|
||||||
|
|
||||||
if (writableStateSet->getMode(GL_ALPHA_TEST) != osg::StateAttribute::INHERIT
|
if (writableStateSet->getMode(GL_ALPHA_TEST) != osg::StateAttribute::INHERIT
|
||||||
&& !previousAddedState->hasMode(GL_ALPHA_TEST))
|
&& !previousAddedState->hasMode(GL_ALPHA_TEST))
|
||||||
removedState->setMode(GL_ALPHA_TEST, writableStateSet->getMode(GL_ALPHA_TEST));
|
removedState->setMode(GL_ALPHA_TEST, writableStateSet->getMode(GL_ALPHA_TEST));
|
||||||
|
@ -14,6 +14,7 @@ uniform sampler2D diffuseMap;
|
|||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
varying vec3 passViewPos;
|
||||||
varying vec3 passNormal;
|
varying vec3 passNormal;
|
||||||
varying float euclideanDepth;
|
varying float euclideanDepth;
|
||||||
varying float linearDepth;
|
varying float linearDepth;
|
||||||
@ -22,6 +23,7 @@ varying float passFalloff;
|
|||||||
uniform vec2 screenRes;
|
uniform vec2 screenRes;
|
||||||
uniform bool useFalloff;
|
uniform bool useFalloff;
|
||||||
uniform float far;
|
uniform float far;
|
||||||
|
uniform float near;
|
||||||
uniform float alphaRef;
|
uniform float alphaRef;
|
||||||
|
|
||||||
#include "lib/material/alpha.glsl"
|
#include "lib/material/alpha.glsl"
|
||||||
@ -30,6 +32,14 @@ uniform float alphaRef;
|
|||||||
#include "compatibility/fog.glsl"
|
#include "compatibility/fog.glsl"
|
||||||
#include "compatibility/shadows_fragment.glsl"
|
#include "compatibility/shadows_fragment.glsl"
|
||||||
|
|
||||||
|
#if @softParticles
|
||||||
|
#include "lib/particle/soft.glsl"
|
||||||
|
|
||||||
|
uniform sampler2D opaqueDepthTex;
|
||||||
|
uniform float particleSize;
|
||||||
|
uniform bool particleFade;
|
||||||
|
#endif
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
@ -48,6 +58,23 @@ void main()
|
|||||||
|
|
||||||
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, far);
|
gl_FragData[0] = applyFogAtDist(gl_FragData[0], euclideanDepth, linearDepth, far);
|
||||||
|
|
||||||
|
#if !defined(FORCE_OPAQUE) && @softParticles
|
||||||
|
vec2 screenCoords = gl_FragCoord.xy / screenRes;
|
||||||
|
vec3 viewVec = normalize(passViewPos.xyz);
|
||||||
|
vec3 viewNormal = normalize(gl_NormalMatrix * passNormal);
|
||||||
|
|
||||||
|
gl_FragData[0].a *= calcSoftParticleFade(
|
||||||
|
viewVec,
|
||||||
|
passViewPos,
|
||||||
|
viewNormal,
|
||||||
|
near,
|
||||||
|
far,
|
||||||
|
texture2D(opaqueDepthTex, screenCoords).x,
|
||||||
|
particleSize,
|
||||||
|
particleFade
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(FORCE_OPAQUE) && FORCE_OPAQUE
|
#if defined(FORCE_OPAQUE) && FORCE_OPAQUE
|
||||||
gl_FragData[0].a = 1.0;
|
gl_FragData[0].a = 1.0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,7 @@ varying vec2 diffuseMapUV;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
varying vec3 passNormal;
|
varying vec3 passNormal;
|
||||||
|
varying vec3 passViewPos;
|
||||||
varying float euclideanDepth;
|
varying float euclideanDepth;
|
||||||
varying float linearDepth;
|
varying float linearDepth;
|
||||||
varying float passFalloff;
|
varying float passFalloff;
|
||||||
@ -41,6 +42,7 @@ void main(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
passColor = gl_Color;
|
passColor = gl_Color;
|
||||||
|
passViewPos = viewPos.xyz;
|
||||||
passNormal = gl_Normal.xyz;
|
passNormal = gl_Normal.xyz;
|
||||||
|
|
||||||
if (useFalloff)
|
if (useFalloff)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user