diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index a5f1032c69..9945a8c40e 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -2708,7 +2708,8 @@ namespace NifOsg stateset->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON); } if (shaderprop->softEffect()) - SceneUtil::setupSoftEffect(*node, shaderprop->mFalloffDepth, true); + SceneUtil::setupSoftEffect( + *node, shaderprop->mFalloffDepth, true, shaderprop->mFalloffDepth); break; } default: diff --git a/components/sceneutil/extradata.cpp b/components/sceneutil/extradata.cpp index d8d3e871dc..720e032a61 100644 --- a/components/sceneutil/extradata.cpp +++ b/components/sceneutil/extradata.cpp @@ -15,7 +15,7 @@ namespace SceneUtil { - void setupSoftEffect(osg::Node& node, float size, bool falloff) + void setupSoftEffect(osg::Node& node, float size, bool falloff, float falloffDepth) { static const osg::ref_ptr depth = new SceneUtil::AutoDepth(osg::Depth::LESS, 0, 1, false); @@ -23,6 +23,7 @@ namespace SceneUtil stateset->addUniform(new osg::Uniform("particleSize", size)); stateset->addUniform(new osg::Uniform("particleFade", falloff)); + stateset->addUniform(new osg::Uniform("softFalloffDepth", falloffDepth)); stateset->setAttributeAndModes(depth, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); node.setUserValue(Misc::OsgUserValues::sXSoftEffect, true); @@ -35,6 +36,8 @@ namespace SceneUtil std::string source; + constexpr float defaultFalloffDepth = 300.f; // arbitrary value that simply looks good with common cases + if (node.getUserValue(Misc::OsgUserValues::sExtraData, source) && !source.empty()) { YAML::Node root = YAML::Load(source); @@ -47,8 +50,9 @@ namespace SceneUtil { auto size = it.second["size"].as(45.f); auto falloff = it.second["falloff"].as(false); + auto falloffDepth = it.second["falloffDepth"].as(defaultFalloffDepth); - setupSoftEffect(node, size, falloff); + setupSoftEffect(node, size, falloff, falloffDepth); } } @@ -56,7 +60,8 @@ namespace SceneUtil } else if (osgParticle::ParticleSystem* partsys = dynamic_cast(&node)) { - setupSoftEffect(node, partsys->getDefaultParticleTemplate().getSizeRange().maximum, false); + setupSoftEffect( + node, partsys->getDefaultParticleTemplate().getSizeRange().maximum, false, defaultFalloffDepth); } traverse(node); diff --git a/components/sceneutil/extradata.hpp b/components/sceneutil/extradata.hpp index ddcb9b6c5c..9b1563b78a 100644 --- a/components/sceneutil/extradata.hpp +++ b/components/sceneutil/extradata.hpp @@ -15,7 +15,7 @@ namespace osg namespace SceneUtil { - void setupSoftEffect(osg::Node& node, float size, bool falloff); + void setupSoftEffect(osg::Node& node, float size, bool falloff, float falloffDepth); class ProcessExtraDataVisitor : public osg::NodeVisitor { diff --git a/docs/source/reference/modding/custom-shader-effects.rst b/docs/source/reference/modding/custom-shader-effects.rst index 340ed5ffed..5ea711953d 100644 --- a/docs/source/reference/modding/custom-shader-effects.rst +++ b/docs/source/reference/modding/custom-shader-effects.rst @@ -31,13 +31,15 @@ This setting can either be activated in the OpenMW launcher or changed in `setti Variables. -+---------+--------------------------------------------------------------------------------------------------------+---------+---------+ -| Name | Description | Type | Default | -+---------+--------------------------------------------------------------------------------------------------------+---------+---------+ -| size | Scaling ratio. Larger values will make a softer fade effect. Larger geometry requires higher values. | integer | 45 | -+---------+--------------------------------------------------------------------------------------------------------+---------+---------+ -| falloff | Fades away geometry as camera gets closer. Geometry full fades when parallel to camera. | boolean | false | -+---------+--------------------------------------------------------------------------------------------------------+---------+---------+ ++--------------+--------------------------------------------------------------------------------------------------------+---------+---------+ +| Name | Description | Type | Default | ++--------------+--------------------------------------------------------------------------------------------------------+---------+---------+ +| size | Scaling ratio. Larger values will make a softer fade effect. Larger geometry requires higher values. | integer | 45 | ++--------------+--------------------------------------------------------------------------------------------------------+---------+---------+ +| falloff | Fades away geometry as camera gets closer. Geometry full fades when parallel to camera. | boolean | false | ++--------------+--------------------------------------------------------------------------------------------------------+---------+---------+ +| falloffDepth | The units at which geometry starts to fade. | float | 300 | ++--------------+--------------------------------------------------------------------------------------------------------+---------+---------+ Example usage. @@ -48,6 +50,7 @@ Example usage. "soft_effect" : { "size": 250, "falloff" : false, + "falloffDepth": 5, } } } diff --git a/files/shaders/compatibility/bs/nolighting.frag b/files/shaders/compatibility/bs/nolighting.frag index c5393d4732..c9e3ca4e13 100644 --- a/files/shaders/compatibility/bs/nolighting.frag +++ b/files/shaders/compatibility/bs/nolighting.frag @@ -38,6 +38,7 @@ uniform float alphaRef; uniform sampler2D opaqueDepthTex; uniform float particleSize; uniform bool particleFade; +uniform float softFalloffDepth; #endif void main() @@ -71,7 +72,8 @@ void main() far, texture2D(opaqueDepthTex, screenCoords).x, particleSize, - particleFade + particleFade, + softFalloffDepth ); #endif diff --git a/files/shaders/compatibility/objects.frag b/files/shaders/compatibility/objects.frag index 4ef463cb34..4caf6c97e2 100644 --- a/files/shaders/compatibility/objects.frag +++ b/files/shaders/compatibility/objects.frag @@ -98,6 +98,7 @@ varying vec3 passNormal; uniform sampler2D opaqueDepthTex; uniform float particleSize; uniform bool particleFade; +uniform float softFalloffDepth; #endif #if @particleOcclusion @@ -256,7 +257,8 @@ vec3 viewNormal = normalize(gl_NormalMatrix * normal); far, texture2D(opaqueDepthTex, screenCoords).x, particleSize, - particleFade + particleFade, + softFalloffDepth ); #endif diff --git a/files/shaders/lib/particle/soft.glsl b/files/shaders/lib/particle/soft.glsl index c415d8402b..99336bc039 100644 --- a/files/shaders/lib/particle/soft.glsl +++ b/files/shaders/lib/particle/soft.glsl @@ -19,7 +19,8 @@ float calcSoftParticleFade( float far, float depth, float size, - bool fade + bool fade, + float softFalloffDepth ) { float euclidianDepth = length(viewPos); @@ -32,13 +33,12 @@ float calcSoftParticleFade( float falloff = size * falloffMultiplier; float delta = particleDepth - sceneDepth; - const float nearMult = 300.0; float viewBias = 1.0; if (fade) { float VdotN = dot(viewDir, viewNormal); - viewBias = abs(VdotN) * quickstep(euclidianDepth / nearMult) * (1.0 - pow(1.0 + VdotN, 1.3)); + viewBias = abs(VdotN) * quickstep(euclidianDepth / softFalloffDepth) * (1.0 - pow(1.0 - abs(VdotN), 1.3)); } const float shift = 0.845;