diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3a66c264b..23fc4ec28 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -251,6 +251,10 @@ namespace MWRender sceneRoot->setNodeMask(Mask_Scene); sceneRoot->setName("Scene Root"); + mUniformRainIntensity = new osg::Uniform("rainIntensity",(float) 0.0); + + mRootNode->getOrCreateStateSet()->addUniform(mUniformRainIntensity); + mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager())); source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); @@ -799,6 +803,7 @@ namespace MWRender { mEffectManager->clear(); mWater->clearRipples(); + mUniformRainIntensity->set((float) 0.0); // for interiors } void RenderingManager::clear() diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index f0087e43d..1673003c4 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -85,6 +85,7 @@ namespace MWRender osg::Uniform* mUniformNear; osg::Uniform* mUniformFar; + osg::Uniform* mUniformRainIntensity; void preloadCommonAssets(); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index e6aa013ec..5bf5dbcb3 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1305,13 +1305,19 @@ public: std::vector > mAlphaFaders; }; -private: +protected: float mAlpha; }; class RainFader : public AlphaFader { public: + + RainFader(osg::Uniform *rainIntensityUniform): AlphaFader() + { + mRainIntensityUniform = rainIntensityUniform; + } + virtual void setDefaults(osg::StateSet* stateset) { osg::ref_ptr mat (new osg::Material); @@ -1320,6 +1326,15 @@ public: mat->setColorMode(osg::Material::OFF); stateset->setAttributeAndModes(mat, osg::StateAttribute::ON); } + + virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + { + AlphaFader::apply(stateset,nv); + mRainIntensityUniform->set((float) (mAlpha * 2.0)); // mAlpha is limited to 0.6 so multiply by 2 to reach full intensity + } + +protected: + osg::Uniform* mRainIntensityUniform; }; void SkyManager::createRain() @@ -1375,7 +1390,7 @@ void SkyManager::createRain() mRainNode->addChild(mRainParticleSystem); mRainNode->addChild(updater); - mRainFader = new RainFader; + mRainFader = new RainFader(mRootNode->getParent(0)->getParent(0)->getStateSet()->getUniform("rainIntensity")); mRainNode->addUpdateCallback(mRainFader); mRainNode->addCullCallback(mUnderwaterSwitch); mRainNode->setNodeMask(Mask_WeatherParticles); diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 863ecc77d..8278c7101 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index 23bd688ab..9da7abc01 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -65,12 +65,14 @@ vec4 circle(vec2 coords, vec2 i_part, float phase) vec2 center = vec2(0.5,0.5) + (0.5 - RAIN_RIPPLE_RADIUS) * (2.0 * randOffset(i_part) - 1.0); vec2 toCenter = coords - center; float d = length(toCenter); + float r = RAIN_RIPPLE_RADIUS * phase; if (d > r) return vec4(0.0,0.0,1.0,0.0); float sinValue = (sin(d / r * 1.2) + 0.7) / 2.0; + float height = (1.0 - abs(phase)) * pow(sinValue,3.0); vec3 normal = normalize(mix(vec3(0.0,0.0,1.0),vec3(normalize(toCenter),0.0),height)); @@ -138,6 +140,8 @@ uniform float near; uniform float far; uniform vec3 nodePosition; +uniform float rainIntensity; + float frustumDepth; float linearizeDepth(float depth) // takes <0,1> non-linear depth value and returns <0,1> linearized value @@ -170,7 +174,13 @@ void main(void) vec3 normal4 = 2.0 * texture2D(normalMap,normalCoords(UV, 1.0, 0.4, waterTimer, -0.02, 0.1, normal3)).rgb - 1.0; vec3 normal5 = 2.0 * texture2D(normalMap,normalCoords(UV, 2.0, 0.7, waterTimer, 0.1, -0.06, normal4)).rgb - 1.0; - vec4 rainRipple = rainCombined(position.xy / 1000.0,waterTimer); + vec4 rainRipple; + + if (rainIntensity > 0.01) + rainRipple = rainCombined(position.xy / 1000.0,waterTimer) * clamp(rainIntensity,0.0,1.0); + else + rainRipple = vec4(0.0,0.0,0.0,0.0); + vec3 rippleAdd = rainRipple.xyz * rainRipple.w * 10.0; vec3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +