Simpler, more lightweight underwater effect, changed colors to match vanilla better

actorid
scrawl 12 years ago
parent 5341bf9504
commit c9fefc7f5d

@ -129,7 +129,6 @@ namespace MWGui
getWidget(mStaticsShadows, "StaticsShadows"); getWidget(mStaticsShadows, "StaticsShadows");
getWidget(mMiscShadows, "MiscShadows"); getWidget(mMiscShadows, "MiscShadows");
getWidget(mShadowsDebug, "ShadowsDebug"); getWidget(mShadowsDebug, "ShadowsDebug");
getWidget(mUnderwaterButton, "UnderwaterButton");
getWidget(mControlsBox, "ControlsBox"); getWidget(mControlsBox, "ControlsBox");
getWidget(mResetControlsButton, "ResetControlsButton"); getWidget(mResetControlsButton, "ResetControlsButton");
getWidget(mInvertYButton, "InvertYButton"); getWidget(mInvertYButton, "InvertYButton");
@ -141,7 +140,6 @@ namespace MWGui
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled);
mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled);
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -236,7 +234,6 @@ namespace MWGui
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}"); mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}");
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}"); mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}"); mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
mUnderwaterButton->setCaptionWithReplacing(Settings::Manager::getBool("underwater effect", "Water") ? "#{sOn}" : "#{sOff}");
mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows")); mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows"));
//mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); //mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}");
@ -267,7 +264,6 @@ namespace MWGui
if (!Settings::Manager::getBool("shaders", "Objects")) if (!Settings::Manager::getBool("shaders", "Objects"))
{ {
mRefractionButton->setEnabled(false); mRefractionButton->setEnabled(false);
mUnderwaterButton->setEnabled (false);
mShadowsEnabledButton->setEnabled(false); mShadowsEnabledButton->setEnabled(false);
} }
@ -389,10 +385,6 @@ namespace MWGui
Settings::Manager::setBool("shader", "Water", newState); Settings::Manager::setBool("shader", "Water", newState);
else if (_sender == mRefractionButton) else if (_sender == mRefractionButton)
Settings::Manager::setBool("refraction", "Water", newState); Settings::Manager::setBool("refraction", "Water", newState);
else if (_sender == mUnderwaterButton)
{
Settings::Manager::setBool("underwater effect", "Water", newState);
}
else if (_sender == mReflectObjectsButton) else if (_sender == mReflectObjectsButton)
{ {
Settings::Manager::setBool("reflect misc", "Water", newState); Settings::Manager::setBool("reflect misc", "Water", newState);
@ -459,10 +451,6 @@ namespace MWGui
{ {
Settings::Manager::setBool("shaders", "Objects", false); Settings::Manager::setBool("shaders", "Objects", false);
mUnderwaterButton->setCaptionWithReplacing("#{sOff}");
mUnderwaterButton->setEnabled(false);
// refraction needs shaders to display underwater fog // refraction needs shaders to display underwater fog
mRefractionButton->setCaptionWithReplacing("#{sOff}"); mRefractionButton->setCaptionWithReplacing("#{sOff}");
mRefractionButton->setEnabled(false); mRefractionButton->setEnabled(false);
@ -485,7 +473,6 @@ namespace MWGui
mReflectTerrainButton->setEnabled(true); mReflectTerrainButton->setEnabled(true);
mRefractionButton->setEnabled(true); mRefractionButton->setEnabled(true);
mUnderwaterButton->setEnabled(true);
mShadowsEnabledButton->setEnabled(true); mShadowsEnabledButton->setEnabled(true);
} }

@ -50,7 +50,6 @@ namespace MWGui
MyGUI::Button* mReflectTerrainButton; MyGUI::Button* mReflectTerrainButton;
MyGUI::Button* mShadersButton; MyGUI::Button* mShadersButton;
MyGUI::Button* mShaderModeButton; MyGUI::Button* mShaderModeButton;
MyGUI::Button* mUnderwaterButton;
MyGUI::Button* mRefractionButton; MyGUI::Button* mRefractionButton;
MyGUI::Button* mShadowsEnabledButton; MyGUI::Button* mShadowsEnabledButton;

@ -56,6 +56,9 @@ enum VisibilityFlags
RV_Debug = 512, RV_Debug = 512,
// overlays, we only want these on the main render target
RV_Overlay = 1024,
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water
}; };

@ -133,8 +133,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("lighting", "true");
sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects"));
sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain")); sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain"));
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0)));
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
@ -355,16 +355,7 @@ void RenderingManager::update (float duration, bool paused)
Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f); Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f);
/* applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam));
if (world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam))
{
mFogColour = Ogre::ColourValue(0.18039, 0.23137, 0.25490);
mFogStart = 0;
mFogEnd = 1500;
}
*/
applyFog();
if(paused) if(paused)
{ {
@ -529,16 +520,20 @@ void RenderingManager::configureFog(const float density, const Ogre::ColourValue
mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density ); mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density );
} }
void RenderingManager::applyFog () void RenderingManager::applyFog (bool underwater)
{ {
mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd); if (!underwater)
{
mRendering.getViewport()->setBackgroundColour (mFogColour); mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd);
mRendering.getViewport()->setBackgroundColour (mFogColour);
mWater->setViewportBackground (mFogColour); mWater->setViewportBackground (mFogColour);
}
sh::Factory::getInstance ().setSharedParameter ("viewportBackground", else
sh::makeProperty<sh::Vector3> (new sh::Vector3(mFogColour.r, mFogColour.g, mFogColour.b))); {
mRendering.getScene()->setFog (FOG_LINEAR, Ogre::ColourValue(0.18039, 0.23137, 0.25490), 0, 0, 1000);
mRendering.getViewport()->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
mWater->setViewportBackground (Ogre::ColourValue(0.18039, 0.23137, 0.25490));
}
} }
void RenderingManager::setAmbientMode() void RenderingManager::setAmbientMode()
@ -784,11 +779,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
rebuild = true; rebuild = true;
} }
else if (it->second == "underwater effect" && it->first == "Water")
{
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
rebuild = true;
}
else if (it->second == "shaders" && it->first == "Objects") else if (it->second == "shaders" && it->first == "Objects")
{ {
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));

@ -208,7 +208,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
sh::Factory* mFactory; sh::Factory* mFactory;
void setAmbientMode(); void setAmbientMode();
void applyFog(); void applyFog(bool underwater);
void setMenuTransparency(float val); void setMenuTransparency(float val);

@ -17,6 +17,8 @@
#include "../mwsound/sound_decoder.hpp" #include "../mwsound/sound_decoder.hpp"
#include "../mwsound/sound.hpp" #include "../mwsound/sound.hpp"
#include "renderconst.hpp"
#ifdef _WIN32 #ifdef _WIN32
#include <BaseTsd.h> #include <BaseTsd.h>
@ -1067,9 +1069,9 @@ VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr)
mBackgroundNode->attachObject(mBackgroundRectangle); mBackgroundNode->attachObject(mBackgroundRectangle);
mRectangle->setVisible(false); mRectangle->setVisible(false);
mRectangle->setVisibilityFlags(0x1); mRectangle->setVisibilityFlags(RV_Overlay);
mBackgroundRectangle->setVisible(false); mBackgroundRectangle->setVisible(false);
mBackgroundRectangle->setVisibilityFlags(0x1); mBackgroundRectangle->setVisibilityFlags(RV_Overlay);
} }
VideoPlayer::~VideoPlayer() VideoPlayer::~VideoPlayer()

@ -4,14 +4,10 @@
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreMeshManager.h> #include <OgreMeshManager.h>
#include <OgreHardwarePixelBuffer.h> #include <OgreHardwarePixelBuffer.h>
#include <OgreCompositorManager.h>
#include <OgreCompositorInstance.h>
#include <OgreCompositorChain.h>
#include <OgreRoot.h> #include <OgreRoot.h>
#include "sky.hpp" #include "sky.hpp"
#include "renderingmanager.hpp" #include "renderingmanager.hpp"
#include "compositors.hpp"
#include "ripplesimulation.hpp" #include "ripplesimulation.hpp"
#include "refraction.hpp" #include "refraction.hpp"
@ -224,16 +220,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend) :
mWater->setMaterial(mMaterial); mWater->setMaterial(mMaterial);
/*
Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh");
underwaterDome->setRenderQueueGroup (RQG_UnderWater);
mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode ();
mUnderwaterDome->attachObject (underwaterDome);
mUnderwaterDome->setScale(10000,10000,10000);
mUnderwaterDome->setVisible(false);
underwaterDome->setMaterialName("Underwater_Dome");
*/
setHeight(mTop); setHeight(mTop);
sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
@ -379,21 +365,11 @@ void Water::updateVisible()
void Water::update(float dt, Ogre::Vector3 player) void Water::update(float dt, Ogre::Vector3 player)
{ {
/*
Ogre::Vector3 pos = mCamera->getDerivedPosition ();
pos.y = -mWaterPlane.d;
mUnderwaterDome->setPosition (pos);
*/
mWaterTimer += dt; mWaterTimer += dt;
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
//if (player.y <= mTop)
{
//mSimulation->addImpulse(Ogre::Vector2(player.x, player.z));
}
mSimulation->update(dt, Ogre::Vector2(player.x, player.y)); mSimulation->update(dt, Ogre::Vector2(player.x, player.y));
if (mReflection) if (mReflection)

@ -25,6 +25,7 @@ namespace Ogre
class SceneNode; class SceneNode;
class Entity; class Entity;
class Vector3; class Vector3;
class Rectangle2D;
struct RenderTargetEvent; struct RenderTargetEvent;
} }
@ -108,8 +109,6 @@ namespace MWRender {
Ogre::SceneNode *mWaterNode; Ogre::SceneNode *mWaterNode;
Ogre::Entity *mWater; Ogre::Entity *mWater;
//Ogre::SceneNode* mUnderwaterDome;
bool mIsUnderwater; bool mIsUnderwater;
bool mActive; bool mActive;
bool mToggled; bool mToggled;

@ -1,7 +1,6 @@
project(resources) project(resources)
set(WATER_FILES set(WATER_FILES
underwater_dome.mesh
water_nm.png water_nm.png
circle.png circle.png
) )

@ -16,7 +16,7 @@
#endif #endif
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING #define UNDERWATER @shGlobalSettingBool(render_refraction)
#define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour) #define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour)
@ -242,18 +242,8 @@
#endif #endif
#if UNDERWATER #if UNDERWATER
shUniform(float, waterLevel) @shSharedParameter(waterLevel)
shUniform(float, waterLevel) @shSharedParameter(waterLevel)
shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0)
shSampler2D(causticMap)
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
shUniform(float, waterEnabled) @shSharedParameter(waterEnabled) shUniform(float, waterEnabled) @shSharedParameter(waterEnabled)
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
#endif #endif
#if VERTEX_LIGHTING #if VERTEX_LIGHTING
@ -305,13 +295,7 @@
#endif #endif
#if UNDERWATER #if UNDERWATER
float3 waterEyePos = float3(1,1,1); float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
// NOTE: this calculation would be wrong for non-uniform scaling
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
if (worldPos.z >= waterLevel || waterEnabled != 1.f)
caustics = float3(1,1,1);
#endif #endif
#if !VERTEX_LIGHTING #if !VERTEX_LIGHTING
@ -358,41 +342,17 @@
#if FOG #if FOG
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
#if UNDERWATER
// regular fog only if fragment is above water #if UNDERWATER
if (worldPos.z > waterLevel || waterEnabled != 1.f) shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, UNDERWATER_COLOUR, shSaturate(length(waterEyePos-worldPos) / VISIBILITY));
#endif #else
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
#endif
#endif #endif
// prevent negative colour output (for example with negative lights) // prevent negative colour output (for example with negative lights)
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
float3 eyeVec = normalize(cameraPos.xyz-worldPos);
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
float3 waterSunColour = float3(0.0,1.0,0.85) *waterSunGradient * 0.5;
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = ( float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3;
float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness;
float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
#endif
} }
#endif #endif

@ -8,6 +8,7 @@ configuration water_reflection
configuration water_refraction configuration water_refraction
{ {
viewproj_fix true viewproj_fix true
render_refraction true
} }
configuration local_map configuration local_map

@ -21,7 +21,7 @@
#define NEED_DEPTH 1 #define NEED_DEPTH 1
#endif #endif
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING #define UNDERWATER @shGlobalSettingBool(render_refraction)
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix) #define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
@ -210,14 +210,6 @@
#if UNDERWATER #if UNDERWATER
shUniform(float, waterLevel) @shSharedParameter(waterLevel) shUniform(float, waterLevel) @shSharedParameter(waterLevel)
shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0)
shSampler2D(causticMap)
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
#endif #endif
@ -242,17 +234,7 @@
float3 caustics = float3(1,1,1); float3 caustics = float3(1,1,1);
#if UNDERWATER #if UNDERWATER
float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
float3 waterEyePos = float3(1,1,1);
// NOTE: this calculation would be wrong for non-uniform scaling
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
if (worldPos.z >= waterLevel)
caustics = float3(1,1,1);
#endif #endif
@ -353,41 +335,14 @@
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
#if UNDERWATER #if UNDERWATER
// regular fog only if fragment is above water shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, UNDERWATER_COLOUR, shSaturate(length(waterEyePos-worldPos) / VISIBILITY));
if (worldPos.z > waterLevel) #else
#endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
#endif
#endif #endif
// prevent negative colour output (for example with negative lights) // prevent negative colour output (for example with negative lights)
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
float3 eyeVec = normalize(cameraPos.xyz-worldPos);
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3;
float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness;
float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
#endif
} }
#endif #endif

@ -1,4 +1,6 @@
#define VISIBILITY 1500.0 // how far you can look through water #define UNDERWATER_COLOUR float3(0.18039, 0.23137, 0.25490)
#define VISIBILITY 1000.0 // how far you can look through water
#define BIG_WAVES_X 0.3 // strength of big waves #define BIG_WAVES_X 0.3 // strength of big waves
#define BIG_WAVES_Y 0.3 #define BIG_WAVES_Y 0.3

@ -56,11 +56,3 @@ material Water
} }
} }
} }
material Underwater_Dome
{
parent openmw_objects_base
depth_write off
}

@ -272,38 +272,16 @@
#if REFRACTION #if REFRACTION
shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz; shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz;
#else #else
shOutputColour(0).xyz = reflection + specular * sunSpecular.xyz; shOutputColour(0).xyz = shLerp(reflection, float3(0.18039, 0.23137, 0.25490), (1.0-fresnel)*0.5) + specular * sunSpecular.xyz;
#endif #endif
// fog // fog
if (isUnderwater == 1) float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
{ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue);
float waterSunGradient = dot(-vVec, -lVec);
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
float waterGradient = dot(-vVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
float darkness = VISIBILITY*2.0;
darkness = clamp((cameraPos.z+darkness)/darkness,0.2,1.0);
float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY);
shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, watercolour * darkness, shSaturate(fog / waterext));
}
else
{
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue);
}
#if REFRACTION #if REFRACTION
shOutputColour(0).w = 1; shOutputColour(0).w = 1;
#else #else
shOutputColour(0).w = shSaturate(fresnel + specular); shOutputColour(0).w = shSaturate(fresnel*2 + specular);
#endif #endif
} }

@ -280,13 +280,6 @@
</Widget> </Widget>
<Widget type="HBox" position="4 135 350 24"> <Widget type="HBox" position="4 135 350 24">
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="UnderwaterButton"/>
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
<Property key="Caption" value="Underwater effects (caustics, fog)"/>
</Widget>
</Widget>
<Widget type="HBox" position="4 182 350 24">
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="RefractionButton"/> <Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="RefractionButton"/>
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top"> <Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
<Property key="Caption" value="Refraction"/> <Property key="Caption" value="Refraction"/>

@ -138,8 +138,6 @@ reflect small statics = false
reflect actors = false reflect actors = false
reflect misc = false reflect misc = false
underwater effect = false
[Sound] [Sound]
# Device name. Blank means default # Device name. Blank means default
device = device =

Binary file not shown.
Loading…
Cancel
Save