Merge pull request #3050 from akortunov/master

Double-buffer shader water stateset
pull/3051/head
Chris Djali 4 years ago committed by GitHub
commit 9bfe941d4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,6 +34,7 @@
Bug #4764: Data race in osg ParticleSystem Bug #4764: Data race in osg ParticleSystem
Bug #4765: Data race in ChunkManager -> Array::setBinding Bug #4765: Data race in ChunkManager -> Array::setBinding
Bug #4774: Guards are ignorant of an invisible player that tries to attack them Bug #4774: Guards are ignorant of an invisible player that tries to attack them
Bug #5026: Data races with rain intensity uniform set by sky and used by water
Bug #5101: Hostile followers travel with the player Bug #5101: Hostile followers travel with the player
Bug #5108: Savegame bloating due to inefficient fog textures format Bug #5108: Savegame bloating due to inefficient fog textures format
Bug #5165: Active spells should use real time intead of timestamps Bug #5165: Active spells should use real time intead of timestamps

@ -370,7 +370,6 @@ namespace MWRender
mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager())); mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager()));
mSky->setCamera(mViewer->getCamera()); mSky->setCamera(mViewer->getCamera());
mSky->setRainIntensityUniform(mWater->getRainIntensityUniform());
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
@ -658,6 +657,9 @@ namespace MWRender
mUnrefQueue->flush(mWorkQueue.get()); mUnrefQueue->flush(mWorkQueue.get());
float rainIntensity = mSky->getPrecipitationAlpha();
mWater->setRainIntensity(rainIntensity);
if (!paused) if (!paused)
{ {
mEffectManager->update(dt); mEffectManager->update(dt);

@ -1113,7 +1113,6 @@ private:
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager) SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager)
: mSceneManager(sceneManager) : mSceneManager(sceneManager)
, mCamera(nullptr) , mCamera(nullptr)
, mRainIntensityUniform(nullptr)
, mAtmosphereNightRoll(0.f) , mAtmosphereNightRoll(0.f)
, mCreated(false) , mCreated(false)
, mIsStorm(false) , mIsStorm(false)
@ -1139,7 +1138,7 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
, mBaseWindSpeed(0.f) , mBaseWindSpeed(0.f)
, mEnabled(true) , mEnabled(true)
, mSunEnabled(true) , mSunEnabled(true)
, mEffectFade(0.f) , mPrecipitationAlpha(0.f)
{ {
osg::ref_ptr<CameraRelativeTransform> skyroot (new CameraRelativeTransform); osg::ref_ptr<CameraRelativeTransform> skyroot (new CameraRelativeTransform);
skyroot->setName("Sky Root"); skyroot->setName("Sky Root");
@ -1163,11 +1162,6 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot); mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
} }
void SkyManager::setRainIntensityUniform(osg::Uniform *uniform)
{
mRainIntensityUniform = uniform;
}
void SkyManager::create() void SkyManager::create()
{ {
assert(!mCreated); assert(!mCreated);
@ -1522,7 +1516,7 @@ void SkyManager::createRain()
osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram); osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram);
program->addOperator(new WrapAroundOperator(mCamera,rainRange)); program->addOperator(new WrapAroundOperator(mCamera,rainRange));
program->addOperator(new WeatherAlphaOperator(mEffectFade, true)); program->addOperator(new WeatherAlphaOperator(mPrecipitationAlpha, true));
program->setParticleSystem(mRainParticleSystem); program->setParticleSystem(mRainParticleSystem);
mRainNode->addChild(program); mRainNode->addChild(program);
@ -1576,30 +1570,21 @@ bool SkyManager::isEnabled()
return mEnabled; return mEnabled;
} }
bool SkyManager::hasRain() bool SkyManager::hasRain() const
{ {
return mRainNode != nullptr; return mRainNode != nullptr;
} }
void SkyManager::update(float duration) float SkyManager::getPrecipitationAlpha() const
{ {
if (!mEnabled) if (mEnabled && !mIsStorm && (hasRain() || mParticleNode))
{ return mPrecipitationAlpha;
if (mRainIntensityUniform)
mRainIntensityUniform->set(0.f);
return;
}
if (mRainIntensityUniform)
{
float rainIntensity = 0.f;
if (!mIsStorm && (hasRain() || mParticleNode))
rainIntensity = mEffectFade;
mRainIntensityUniform->set(rainIntensity); return 0.f;
} }
void SkyManager::update(float duration)
{
switchUnderwaterRain(); switchUnderwaterRain();
if (mIsStorm) if (mIsStorm)
@ -1737,7 +1722,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(new SceneUtil::FrameTimeSource)); SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(new SceneUtil::FrameTimeSource));
mParticleEffect->accept(assignVisitor); mParticleEffect->accept(assignVisitor);
AlphaFader::SetupVisitor alphaFaderSetupVisitor(mEffectFade); AlphaFader::SetupVisitor alphaFaderSetupVisitor(mPrecipitationAlpha);
mParticleEffect->accept(alphaFaderSetupVisitor); mParticleEffect->accept(alphaFaderSetupVisitor);
@ -1754,7 +1739,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram); osg::ref_ptr<osgParticle::ModularProgram> program (new osgParticle::ModularProgram);
if (!mIsStorm) if (!mIsStorm)
program->addOperator(new WrapAroundOperator(mCamera,osg::Vec3(1024,1024,800))); program->addOperator(new WrapAroundOperator(mCamera,osg::Vec3(1024,1024,800)));
program->addOperator(new WeatherAlphaOperator(mEffectFade, false)); program->addOperator(new WeatherAlphaOperator(mPrecipitationAlpha, false));
program->setParticleSystem(ps); program->setParticleSystem(ps);
mParticleNode->addChild(program); mParticleNode->addChild(program);
} }
@ -1843,7 +1828,7 @@ void SkyManager::setWeather(const WeatherResult& weather)
mAtmosphereNightNode->setNodeMask(weather.mNight ? ~0 : 0); mAtmosphereNightNode->setNodeMask(weather.mNight ? ~0 : 0);
mEffectFade = weather.mEffectFade; mPrecipitationAlpha = weather.mPrecipitationAlpha;
} }
float SkyManager::getBaseWindSpeed() const float SkyManager::getBaseWindSpeed() const

@ -7,7 +7,6 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Vec4f> #include <osg/Vec4f>
#include <osg/Uniform>
namespace osg namespace osg
{ {
@ -88,7 +87,7 @@ namespace MWRender
std::string mParticleEffect; std::string mParticleEffect;
std::string mRainEffect; std::string mRainEffect;
float mEffectFade; float mPrecipitationAlpha;
float mRainDiameter; float mRainDiameter;
float mRainMinHeight; float mRainMinHeight;
@ -157,7 +156,9 @@ namespace MWRender
bool isEnabled(); bool isEnabled();
bool hasRain(); bool hasRain() const;
float getPrecipitationAlpha() const;
void setRainSpeed(float speed); void setRainSpeed(float speed);
@ -180,8 +181,6 @@ namespace MWRender
void setCamera(osg::Camera *camera); void setCamera(osg::Camera *camera);
void setRainIntensityUniform(osg::Uniform *uniform);
float getBaseWindSpeed() const; float getBaseWindSpeed() const;
private: private:
@ -196,7 +195,6 @@ namespace MWRender
Resource::SceneManager* mSceneManager; Resource::SceneManager* mSceneManager;
osg::Camera *mCamera; osg::Camera *mCamera;
osg::Uniform *mRainIntensityUniform;
osg::ref_ptr<osg::Group> mRootNode; osg::ref_ptr<osg::Group> mRootNode;
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot; osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
@ -271,7 +269,7 @@ namespace MWRender
bool mEnabled; bool mEnabled;
bool mSunEnabled; bool mSunEnabled;
float mEffectFade; float mPrecipitationAlpha;
osg::Vec4f mMoonScriptColor; osg::Vec4f mMoonScriptColor;
}; };

@ -208,6 +208,37 @@ public:
} }
}; };
class RainIntensityUpdater : public SceneUtil::StateSetUpdater
{
public:
RainIntensityUpdater()
: mRainIntensity(0.f)
{
}
void setRainIntensity(float rainIntensity)
{
mRainIntensity = rainIntensity;
}
protected:
void setDefaults(osg::StateSet* stateset) override
{
osg::ref_ptr<osg::Uniform> rainIntensityUniform = new osg::Uniform("rainIntensity", 0.0f);
stateset->addUniform(rainIntensityUniform.get());
}
void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override
{
osg::ref_ptr<osg::Uniform> rainIntensityUniform = stateset->getUniform("rainIntensity");
if (rainIntensityUniform != nullptr)
rainIntensityUniform->set(mRainIntensity);
}
private:
float mRainIntensity;
};
osg::ref_ptr<osg::Image> readPngImage (const std::string& file) osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
{ {
// use boost in favor of osgDB::readImage, to handle utf-8 path issues on Windows // use boost in favor of osgDB::readImage, to handle utf-8 path issues on Windows
@ -431,7 +462,8 @@ public:
Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem,
osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath) osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath)
: mParent(parent) : mRainIntensityUpdater(nullptr)
, mParent(parent)
, mSceneRoot(sceneRoot) , mSceneRoot(sceneRoot)
, mResourceSystem(resourceSystem) , mResourceSystem(resourceSystem)
, mResourcePath(resourcePath) , mResourcePath(resourcePath)
@ -463,8 +495,6 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
setHeight(mTop); setHeight(mTop);
mRainIntensityUniform = new osg::Uniform("rainIntensity",(float) 0.0);
updateWaterMaterial(); updateWaterMaterial();
if (ico) if (ico)
@ -494,11 +524,6 @@ void Water::setCullCallback(osg::Callback* callback)
} }
} }
osg::Uniform *Water::getRainIntensityUniform()
{
return mRainIntensityUniform.get();
}
void Water::updateWaterMaterial() void Water::updateWaterMaterial()
{ {
if (mReflection) if (mReflection)
@ -556,6 +581,8 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha)
osg::ref_ptr<osg::StateSet> stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water); osg::ref_ptr<osg::StateSet> stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water);
node->setStateSet(stateset); node->setStateSet(stateset);
node->setUpdateCallback(nullptr);
mRainIntensityUpdater = nullptr;
// Add animated textures // Add animated textures
std::vector<osg::ref_ptr<osg::Texture2D> > textures; std::vector<osg::ref_ptr<osg::Texture2D> > textures;
@ -639,15 +666,15 @@ void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, R
shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
shaderStateset->addUniform(mRainIntensityUniform.get());
osg::ref_ptr<osg::Program> program (new osg::Program); osg::ref_ptr<osg::Program> program (new osg::Program);
program->addShader(vertexShader); program->addShader(vertexShader);
program->addShader(fragmentShader); program->addShader(fragmentShader);
shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON); shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON);
node->setStateSet(shaderStateset); node->setStateSet(shaderStateset);
node->setUpdateCallback(nullptr);
mRainIntensityUpdater = new RainIntensityUpdater();
node->setUpdateCallback(mRainIntensityUpdater);
} }
void Water::processChangedSettings(const Settings::CategorySettingVector& settings) void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
@ -730,6 +757,12 @@ void Water::setHeight(const float height)
mRefraction->setWaterLevel(mTop); mRefraction->setWaterLevel(mTop);
} }
void Water::setRainIntensity(float rainIntensity)
{
if (mRainIntensityUpdater)
mRainIntensityUpdater->setRainIntensity(rainIntensity);
}
void Water::update(float dt) void Water::update(float dt)
{ {
mSimulation->update(dt); mSimulation->update(dt);

@ -6,7 +6,6 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Vec3f> #include <osg/Vec3f>
#include <osg/Uniform>
#include <osg/Camera> #include <osg/Camera>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -46,11 +45,12 @@ namespace MWRender
class Refraction; class Refraction;
class Reflection; class Reflection;
class RippleSimulation; class RippleSimulation;
class RainIntensityUpdater;
/// Water rendering /// Water rendering
class Water class Water
{ {
osg::ref_ptr<osg::Uniform> mRainIntensityUniform; osg::ref_ptr<RainIntensityUpdater> mRainIntensityUpdater;
osg::ref_ptr<osg::Group> mParent; osg::ref_ptr<osg::Group> mParent;
osg::ref_ptr<osg::Group> mSceneRoot; osg::ref_ptr<osg::Group> mSceneRoot;
@ -112,6 +112,7 @@ namespace MWRender
void changeCell(const MWWorld::CellStore* store); void changeCell(const MWWorld::CellStore* store);
void setHeight(const float height); void setHeight(const float height);
void setRainIntensity(const float rainIntensity);
void update(float dt); void update(float dt);
@ -119,8 +120,6 @@ namespace MWRender
osg::Camera *getRefractionCamera(); osg::Camera *getRefractionCamera();
void processChangedSettings(const Settings::CategorySettingVector& settings); void processChangedSettings(const Settings::CategorySettingVector& settings);
osg::Uniform *getRainIntensityUniform();
}; };
} }

@ -1129,7 +1129,7 @@ inline void WeatherManager::calculateResult(const int weatherID, const float gam
mResult.mGlareView = current.mGlareView; mResult.mGlareView = current.mGlareView;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID; mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mAmbientSoundVolume = 1.f; mResult.mAmbientSoundVolume = 1.f;
mResult.mEffectFade = 1.f; mResult.mPrecipitationAlpha = 1.f;
mResult.mIsStorm = current.mIsStorm; mResult.mIsStorm = current.mIsStorm;
@ -1236,7 +1236,7 @@ inline void WeatherManager::calculateTransitionResult(const float factor, const
mResult.mRainSpeed = current.mRainSpeed; mResult.mRainSpeed = current.mRainSpeed;
mResult.mRainEntranceSpeed = current.mRainEntranceSpeed; mResult.mRainEntranceSpeed = current.mRainEntranceSpeed;
mResult.mAmbientSoundVolume = 1 - factor / threshold; mResult.mAmbientSoundVolume = 1 - factor / threshold;
mResult.mEffectFade = mResult.mAmbientSoundVolume; mResult.mPrecipitationAlpha = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID; mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mRainDiameter = current.mRainDiameter; mResult.mRainDiameter = current.mRainDiameter;
mResult.mRainMinHeight = current.mRainMinHeight; mResult.mRainMinHeight = current.mRainMinHeight;
@ -1251,7 +1251,7 @@ inline void WeatherManager::calculateTransitionResult(const float factor, const
mResult.mRainSpeed = other.mRainSpeed; mResult.mRainSpeed = other.mRainSpeed;
mResult.mRainEntranceSpeed = other.mRainEntranceSpeed; mResult.mRainEntranceSpeed = other.mRainEntranceSpeed;
mResult.mAmbientSoundVolume = (factor - threshold) / (1 - threshold); mResult.mAmbientSoundVolume = (factor - threshold) / (1 - threshold);
mResult.mEffectFade = mResult.mAmbientSoundVolume; mResult.mPrecipitationAlpha = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = other.mAmbientLoopSoundID; mResult.mAmbientLoopSoundID = other.mAmbientLoopSoundID;
mResult.mRainDiameter = other.mRainDiameter; mResult.mRainDiameter = other.mRainDiameter;

Loading…
Cancel
Save