mirror of https://github.com/OpenMW/openmw.git
Merge branch 'soften_me_up_like_one_of_your_french_meshes' into 'master'
Allow soft particle effect on any NIF See merge request OpenMW/openmw!2015precompile_headers
commit
56187ad977
@ -0,0 +1,66 @@
|
||||
#include "extradata.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <osg/Node>
|
||||
#include <osg/ValueObject>
|
||||
#include <osgParticle/ParticleSystem>
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include <components/misc/osguservalues.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
#include <components/serialization/osgyaml.hpp>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
void ProcessExtraDataVisitor::setupSoftEffect(osg::Node& node, float size, bool falloff)
|
||||
{
|
||||
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);
|
||||
|
||||
osg::StateSet* stateset = node.getOrCreateStateSet();
|
||||
|
||||
stateset->addUniform(new osg::Uniform("opaqueDepthTex", unitSoftEffect));
|
||||
stateset->addUniform(new osg::Uniform("particleSize", size));
|
||||
stateset->addUniform(new osg::Uniform("particleFade", falloff));
|
||||
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||
|
||||
node.setUserValue(Misc::OsgUserValues::sXSoftEffect, true);
|
||||
}
|
||||
|
||||
void ProcessExtraDataVisitor::apply(osg::Node& node)
|
||||
{
|
||||
std::string source;
|
||||
|
||||
if (node.getUserValue(Misc::OsgUserValues::sExtraData, source) && !source.empty())
|
||||
{
|
||||
YAML::Node root = YAML::Load(source);
|
||||
|
||||
for (const auto& it : root["shader"])
|
||||
{
|
||||
std::string key = it.first.as<std::string>();
|
||||
|
||||
if (key == "soft_effect")
|
||||
{
|
||||
auto size = it.second["size"].as<float>(45.f);
|
||||
auto falloff = it.second["falloff"].as<bool>(false);
|
||||
|
||||
setupSoftEffect(node, size, falloff);
|
||||
}
|
||||
}
|
||||
|
||||
node.setUserValue(Misc::OsgUserValues::sExtraData, std::string{});
|
||||
}
|
||||
else if (osgParticle::ParticleSystem* partsys = dynamic_cast<osgParticle::ParticleSystem*>(&node))
|
||||
{
|
||||
setupSoftEffect(node, partsys->getDefaultParticleTemplate().getSizeRange().maximum, false);
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#ifndef OPENMW_COMPONENTS_RESOURCE_EXTRADATA_H
|
||||
#define OPENMW_COMPONENTS_RESOURCE_EXTRADATA_H
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/StateAttribute>
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class SceneManager;
|
||||
}
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
class ProcessExtraDataVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
ProcessExtraDataVisitor(Resource::SceneManager* sceneMgr) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mSceneMgr(sceneMgr) {}
|
||||
|
||||
void apply(osg::Node& node) override;
|
||||
|
||||
private:
|
||||
void setupSoftEffect(osg::Node& node, float size, bool falloff);
|
||||
|
||||
Resource::SceneManager* mSceneMgr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
Custom Shader Effects
|
||||
#####################
|
||||
|
||||
OpenMW leverages the `NiStringExtraData` node to inject special shader flags and effects.
|
||||
This nodes must have the prefix `omw:data` and have a valid JSON object that follows.
|
||||
|
||||
.. note::
|
||||
|
||||
This is a new feature to inject OpenMW specific effects. Only a single
|
||||
effect is currently supported. By default, the shader effects will propogate
|
||||
to all a nodes children. Other propogation modes and effects will come with
|
||||
future releases.
|
||||
|
||||
See below to see the currently supported effects.
|
||||
|
||||
Soft Effect
|
||||
-----------
|
||||
|
||||
This effect softens the intersection of alpha-blended planes with other opaque
|
||||
geometry. This effect is automatically applied to all particle systems, but can
|
||||
be applied to any mesh or node. This is useful when layering many alpha-blended
|
||||
planes for various effects like steam over a hotspring or low hanging fog for
|
||||
dungeons.
|
||||
|
||||
To use this feature the :ref:`soft particles` setting must be enabled.
|
||||
This settings can either be activated in the OpenMW launcher or changed in `settings.cfg`:
|
||||
|
||||
::
|
||||
|
||||
[Shaders]
|
||||
soft particles = true
|
||||
|
||||
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 |
|
||||
+---------+--------------------------------------------------------------------------------------------------------+---------+---------+
|
||||
|
||||
Example usage.
|
||||
|
||||
::
|
||||
|
||||
omw:data {
|
||||
"shader" : {
|
||||
"soft_effect" : {
|
||||
"size": 250,
|
||||
"falloff" : false,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue