mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-08-03 15:27:13 -04:00
Merge branch 'underwater_sun' into 'master'
Fix sun flash and glare rendering underwater (#8083) See merge request OpenMW/openmw!4388
This commit is contained in:
commit
c39d9490d6
@ -24,6 +24,7 @@ Programmers
|
||||
Aleksandar Jovanov
|
||||
Alex Haddad (rainChu)
|
||||
Alex McKibben
|
||||
Alexander Booher (Sleepy_wade)
|
||||
alexanderkjall
|
||||
Alexander Nadeau (wareya)
|
||||
Alexander Olofsson (Ananace)
|
||||
|
@ -286,6 +286,7 @@
|
||||
Bug #8048: Actors can generate negative collision extents and have no collision
|
||||
Bug #8063: menu_background.bik video with audio freezes the game forever
|
||||
Bug #8064: Lua move360 script doesn't respect the enableZoom/disableZoom Camera interface setting
|
||||
Bug #8083: Sun glare visible when underwater
|
||||
Bug #8085: Don't search in scripts or shaders directories for "Select directories you wish to add" menu in launcher
|
||||
Bug #8097: GetEffect doesn't detect 0 magnitude spells
|
||||
Bug #8099: Reaching Lua memory limit leads to a crash
|
||||
|
@ -543,6 +543,7 @@ namespace MWRender
|
||||
return;
|
||||
|
||||
switchUnderwaterRain();
|
||||
switchUnderwaterSun();
|
||||
|
||||
if (mIsStorm && mParticleNode)
|
||||
{
|
||||
@ -640,6 +641,14 @@ namespace MWRender
|
||||
mRainParticleSystem->setFrozen(freeze);
|
||||
}
|
||||
|
||||
void SkyManager::switchUnderwaterSun()
|
||||
{
|
||||
if (!mSun)
|
||||
return;
|
||||
bool underwater = mUnderwaterSwitch->isUnderwater();
|
||||
mSun->setUnderwater(underwater);
|
||||
}
|
||||
|
||||
void SkyManager::setWeather(const WeatherResult& weather)
|
||||
{
|
||||
if (!mCreated)
|
||||
|
@ -112,6 +112,7 @@ namespace MWRender
|
||||
void createRain();
|
||||
void destroyRain();
|
||||
void switchUnderwaterRain();
|
||||
void switchUnderwaterSun();
|
||||
void updateRainParameters();
|
||||
|
||||
Resource::SceneManager* mSceneManager;
|
||||
|
@ -133,47 +133,87 @@ namespace MWRender
|
||||
{
|
||||
}
|
||||
|
||||
float OcclusionCallback::getVisibleRatio(osg::Camera* camera)
|
||||
float OcclusionCallback::getVisibleRatio(osg::Camera* camera, bool smooth)
|
||||
{
|
||||
float visibleRatio = updateVisibleRatio(camera);
|
||||
float dt = MWBase::Environment::get().getFrameDuration();
|
||||
|
||||
if (smooth)
|
||||
{
|
||||
float lastRatio = mLastRatio[osg::observer_ptr<osg::Camera>(camera)];
|
||||
|
||||
float change = dt * 5;
|
||||
|
||||
if (visibleRatio > lastRatio)
|
||||
visibleRatio = std::min(visibleRatio, lastRatio + change);
|
||||
else
|
||||
visibleRatio = std::max(visibleRatio, lastRatio - change);
|
||||
}
|
||||
|
||||
mLastRatio[osg::observer_ptr<osg::Camera>(camera)] = visibleRatio;
|
||||
return visibleRatio;
|
||||
}
|
||||
|
||||
OcclusionCallback::~OcclusionCallback() {}
|
||||
|
||||
float OcclusionCallback::updateVisibleRatio(osg::Camera* camera)
|
||||
{
|
||||
int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera);
|
||||
int total = mOcclusionQueryTotalPixels->getQueryGeometry()->getNumPixels(camera);
|
||||
|
||||
float visibleRatio = 0.f;
|
||||
|
||||
if (total > 0)
|
||||
visibleRatio = static_cast<float>(visible) / static_cast<float>(total);
|
||||
|
||||
float dt = MWBase::Environment::get().getFrameDuration();
|
||||
|
||||
float lastRatio = mLastRatio[osg::observer_ptr<osg::Camera>(camera)];
|
||||
|
||||
float change = dt * 10;
|
||||
|
||||
if (visibleRatio > lastRatio)
|
||||
visibleRatio = std::min(visibleRatio, lastRatio + change);
|
||||
else
|
||||
visibleRatio = std::max(visibleRatio, lastRatio - change);
|
||||
|
||||
mLastRatio[osg::observer_ptr<osg::Camera>(camera)] = visibleRatio;
|
||||
|
||||
return visibleRatio;
|
||||
}
|
||||
|
||||
SunOcclusionCallback::SunOcclusionCallback(
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal)
|
||||
: OcclusionCallback(oqnVisible, oqnTotal)
|
||||
, mUnderwater(false)
|
||||
{
|
||||
}
|
||||
|
||||
SunOcclusionCallback::~SunOcclusionCallback() {}
|
||||
|
||||
float SunOcclusionCallback::updateVisibleRatio(osg::Camera* camera)
|
||||
{
|
||||
if (mUnderwater)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
return OcclusionCallback::updateVisibleRatio(camera);
|
||||
}
|
||||
|
||||
void SunOcclusionCallback::setUnderwater(bool underwater)
|
||||
{
|
||||
mUnderwater = underwater;
|
||||
}
|
||||
|
||||
bool SunOcclusionCallback::isUnderwater()
|
||||
{
|
||||
return mUnderwater;
|
||||
}
|
||||
|
||||
/// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a
|
||||
/// cull callback.
|
||||
class SunFlashCallback : public OcclusionCallback,
|
||||
class SunFlashCallback : public SunOcclusionCallback,
|
||||
public SceneUtil::NodeCallback<SunFlashCallback, osg::Node*, osgUtil::CullVisitor*>
|
||||
{
|
||||
public:
|
||||
SunFlashCallback(
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal)
|
||||
: OcclusionCallback(std::move(oqnVisible), std::move(oqnTotal))
|
||||
: SunOcclusionCallback(std::move(oqnVisible), std::move(oqnTotal))
|
||||
, mGlareView(1.f)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SunFlashCallback() {}
|
||||
|
||||
void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
|
||||
{
|
||||
float visibleRatio = getVisibleRatio(cv->getCurrentCamera());
|
||||
float visibleRatio = getVisibleRatio(cv->getCurrentCamera(), !isUnderwater());
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset;
|
||||
|
||||
@ -232,13 +272,13 @@ namespace MWRender
|
||||
|
||||
/// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between
|
||||
/// sun and camera. Must be attached as a cull callback to the node above the glare node.
|
||||
class SunGlareCallback : public OcclusionCallback,
|
||||
class SunGlareCallback : public SunOcclusionCallback,
|
||||
public SceneUtil::NodeCallback<SunGlareCallback, osg::Node*, osgUtil::CullVisitor*>
|
||||
{
|
||||
public:
|
||||
SunGlareCallback(osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible,
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal, osg::ref_ptr<osg::PositionAttitudeTransform> sunTransform)
|
||||
: OcclusionCallback(std::move(oqnVisible), std::move(oqnTotal))
|
||||
: SunOcclusionCallback(std::move(oqnVisible), std::move(oqnTotal))
|
||||
, mSunTransform(std::move(sunTransform))
|
||||
, mTimeOfDayFade(1.f)
|
||||
, mGlareView(1.f)
|
||||
@ -255,10 +295,12 @@ namespace MWRender
|
||||
mColor[i] = std::min(1.f, mColor[i]);
|
||||
}
|
||||
|
||||
virtual ~SunGlareCallback() {}
|
||||
|
||||
void operator()(osg::Node* node, osgUtil::CullVisitor* cv)
|
||||
{
|
||||
float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix());
|
||||
float visibleRatio = getVisibleRatio(cv->getCurrentCamera());
|
||||
float visibleRatio = getVisibleRatio(cv->getCurrentCamera(), !isUnderwater());
|
||||
|
||||
const float angleMaxRadians = osg::DegreesToRadians(mSunGlareFaderAngleMax);
|
||||
|
||||
@ -831,6 +873,14 @@ namespace MWRender
|
||||
mSunFlashCallback->setGlareView(ratio);
|
||||
}
|
||||
|
||||
void Sun::setUnderwater(bool underwater)
|
||||
{
|
||||
if (mSunFlashCallback)
|
||||
mSunFlashCallback->setUnderwater(underwater);
|
||||
if (mSunGlareCallback)
|
||||
mSunGlareCallback->setUnderwater(underwater);
|
||||
}
|
||||
|
||||
void Sun::setDirection(const osg::Vec3f& direction)
|
||||
{
|
||||
osg::Vec3f normalizedDirection = direction / direction.length();
|
||||
|
@ -113,17 +113,32 @@ namespace MWRender
|
||||
public:
|
||||
OcclusionCallback(
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal);
|
||||
float getVisibleRatio(osg::Camera* camera, bool smooth);
|
||||
virtual ~OcclusionCallback();
|
||||
|
||||
protected:
|
||||
float getVisibleRatio(osg::Camera* camera);
|
||||
virtual float updateVisibleRatio(osg::Camera* camera);
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryVisiblePixels;
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryTotalPixels;
|
||||
|
||||
std::map<osg::observer_ptr<osg::Camera>, float> mLastRatio;
|
||||
};
|
||||
|
||||
class SunOcclusionCallback : public OcclusionCallback
|
||||
{
|
||||
public:
|
||||
SunOcclusionCallback(
|
||||
osg::ref_ptr<osg::OcclusionQueryNode> oqnVisible, osg::ref_ptr<osg::OcclusionQueryNode> oqnTotal);
|
||||
virtual ~SunOcclusionCallback();
|
||||
virtual float updateVisibleRatio(osg::Camera* camera) override;
|
||||
void setUnderwater(bool underwater);
|
||||
bool isUnderwater();
|
||||
|
||||
private:
|
||||
bool mUnderwater;
|
||||
};
|
||||
|
||||
class AtmosphereUpdater : public SceneUtil::StateSetUpdater
|
||||
{
|
||||
public:
|
||||
@ -249,7 +264,7 @@ namespace MWRender
|
||||
|
||||
void setColor(const osg::Vec4f& color);
|
||||
void adjustTransparency(const float ratio) override;
|
||||
|
||||
void setUnderwater(bool underwater);
|
||||
void setDirection(const osg::Vec3f& direction);
|
||||
void setGlareTimeOfDayFade(float val);
|
||||
void setSunglare(bool enabled);
|
||||
|
Loading…
x
Reference in New Issue
Block a user