diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index c5c6eada2..343c96cec 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -123,6 +123,7 @@ namespace MWGui getWidget(mInvertYButton, "InvertYButton"); getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); + getWidget(mRefractionButton, "RefractionButton"); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -133,6 +134,7 @@ namespace MWGui mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); + mRefractionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -248,6 +250,8 @@ namespace MWGui mShadersButton->setCaption (Settings::Manager::getBool("shaders", "Objects") ? "on" : "off"); mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General")); + mRefractionButton->setCaption (Settings::Manager::getBool("refraction", "Water") ? "on" : "off"); + if (!MWRender::RenderingManager::waterShaderSupported()) { mWaterShaderButton->setEnabled(false); @@ -376,6 +380,8 @@ namespace MWGui { if (_sender == mWaterShaderButton) Settings::Manager::setBool("shader", "Water", newState); + else if (_sender == mRefractionButton) + Settings::Manager::setBool("refraction", "Water", newState); else if (_sender == mUnderwaterButton) { Settings::Manager::setBool("underwater effect", "Water", newState); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 8ca3ad758..55cc0a870 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -51,6 +51,7 @@ namespace MWGui MyGUI::Button* mShadersButton; MyGUI::Button* mShaderModeButton; MyGUI::Button* mUnderwaterButton; + MyGUI::Button* mRefractionButton; MyGUI::Button* mShadowsEnabledButton; MyGUI::Button* mShadowsLargeDistance; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index aa73bc49b..69f3914e5 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -135,8 +135,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); - sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( - 1.f))); + sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); applyCompositors(); @@ -757,6 +756,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { bool changeRes = false; + bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) { @@ -794,18 +794,23 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec applyCompositors(); sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); - mObjects.rebuildStaticGeometry (); + rebuild = true; mRendering.getViewport ()->setClearEveryFrame (true); } + else if (it->second == "refraction" && it->first == "Water") + { + sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); + rebuild = true; + } else if (it->second == "underwater effect" && it->first == "Water") { sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->second == "shaders" && it->first == "Objects") { sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->second == "shader mode" && it->first == "General") { @@ -818,13 +823,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec else lang = sh::Language_CG; sh::Factory::getInstance ().setCurrentLanguage (lang); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->first == "Shadows") { mShadows->recreate (); - mObjects.rebuildStaticGeometry (); + rebuild = true; } } @@ -842,6 +847,9 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (mWater) mWater->processChangedSettings(settings); + + if (rebuild) + mObjects.rebuildStaticGeometry(); } void RenderingManager::setMenuTransparency(float val) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index f2854c879..433aa8af8 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -430,8 +430,11 @@ void Water::applyRTT() delete mRefraction; mRefraction = NULL; - mRefraction = new Refraction(mCamera); - mRefraction->setHeight(mTop); + if (Settings::Manager::getBool("refraction", "Water")) + { + mRefraction = new Refraction(mCamera); + mRefraction->setHeight(mTop); + } } void Water::applyVisibilityMask() @@ -455,7 +458,8 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin it != settings.end(); ++it) { if ( it->first == "Water" && ( - it->second == "shader" + it->second == "shader" + || it->second == "refraction" || it->second == "rtt size")) applyRT = true; diff --git a/files/materials/core.h b/files/materials/core.h index e498a3809..3385e5fac 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -1,9 +1,3 @@ -//#define gammaCorrectRead(v) pow(max(v, 0.00001f), float3(gammaCorrection,gammaCorrection,gammaCorrection)) -//#define gammaCorrectOutput(v) pow(max(v, 0.00001f), float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) - -#define gammaCorrectRead(v) v -#define gammaCorrectOutput(v) v - #if SH_HLSL == 1 || SH_CG == 1 #define shTexture2D sampler2D diff --git a/files/materials/objects.shader b/files/materials/objects.shader index c68705c42..1e9c4a334 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -112,8 +112,6 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) #endif - //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) @@ -180,7 +178,6 @@ SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV); - shOutputColour(0).xyz = gammaCorrectRead(shOutputColour(0).xyz); #if LIGHTING float3 normal = normalize(normalPassthrough); @@ -271,7 +268,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel || waterEnabled != 1.f) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -286,11 +283,11 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85)) *waterSunGradient * 0.5; + 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 = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.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.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -303,8 +300,6 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); #endif - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depthPassthrough / far,1,1,1); #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index dfe998210..9b891e1e8 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -137,8 +137,6 @@ shSampler2D(normalMap) // global normal map - //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - @shForeach(@shPropertyString(num_blendmaps)) shSampler2D(blendMap@shIterator) @@ -254,9 +252,9 @@ #if IS_FIRST_PASS == 1 && @shIterator == 0 // first layer of first pass doesn't need a blend map - albedo = gammaCorrectRead(shSample(diffuseMap0, UV * 10).rgb); + albedo = shSample(diffuseMap0, UV * 10).rgb; #else - albedo = shLerp(albedo, gammaCorrectRead(shSample(diffuseMap@shIterator, UV * 10).rgb), blendValues@shPropertyString(blendmap_component_@shIterator)); + albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); #endif @shEndForeach @@ -343,7 +341,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -358,12 +356,12 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; + 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 = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; - float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction + 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.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -376,8 +374,6 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); #endif - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depth / far,1,1,1); #endif diff --git a/files/materials/water.mat b/files/materials/water.mat index 2717f26fc..7546606fc 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -11,6 +11,9 @@ material Water fragment_program water_fragment cull_hardware none + + scene_blend alpha_blend + depth_write off texture_unit reflectionMap { diff --git a/files/materials/water.shader b/files/materials/water.shader index dbe36a91c..b02b4761c 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -62,6 +62,7 @@ // Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html ) #define RIPPLES 1 +#define REFRACTION @shGlobalSettingBool(refraction) #ifdef SH_VERTEX_SHADER @@ -123,9 +124,9 @@ #define REFR_BUMP 0.12 // refraction distortion amount #define SCATTER_AMOUNT 3.0 // amount of sunlight scattering - #define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering + #define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering - #define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction + #define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction #define SPEC_HARDNESS 256 // specular highlights hardness @@ -168,7 +169,9 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) shSampler2D(reflectionMap) +#if REFRACTION shSampler2D(refractionMap) +#endif shSampler2D(depthMap) shSampler2D(normalMap) @@ -186,9 +189,6 @@ shUniform(float4, sunPosition) @shAutoConstant(sunPosition, light_position, 0) shUniform(float4, sunSpecular) @shAutoConstant(sunSpecular, light_specular_colour, 0) - - shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - shUniform(float, renderTargetFlipping) @shAutoConstant(renderTargetFlipping, render_target_flipping) @@ -255,7 +255,7 @@ float s = shSaturate(dot(lR, vVec)*2.0-1.2); float lightScatter = shSaturate(dot(-lVec,lNormal)*0.7+0.3) * s * SCATTER_AMOUNT * waterSunFade_sunHeight.x * shSaturate(1.0-exp(-waterSunFade_sunHeight.y)); - float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*gammaCorrectRead(float3(1.0,0.4,0.0)), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); + float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*float3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); // fresnel float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air @@ -264,32 +264,36 @@ fresnel = shSaturate(fresnel); // reflection - float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb); + float3 reflection = shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb; // refraction float3 R = reflect(vVec, normal); - float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(normal.xz*REFR_BUMP))*1.0).rgb); +#if REFRACTION + float3 refraction = shSample(refractionMap, (screenCoords-(normal.xz*REFR_BUMP))*1.0).rgb; // brighten up the refraction underwater refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction; - +#endif // specular float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS); +#if REFRACTION shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz; - +#else + shOutputColour(0).xyz = reflection + specular * sunSpecular.xyz; +#endif // fog if (isUnderwater == 1) { float waterSunGradient = dot(-vVec, -lVec); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; + 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 = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; - float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction + 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; @@ -302,11 +306,14 @@ else { float fogValue = shSaturate((length(cameraPos.xyz-position.xyz) - fogParams.y) * fogParams.w); - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColor), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); } - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); +#if REFRACTION shOutputColour(0).w = 1; +#else + shOutputColour(0).w = shSaturate(fresnel + specular); +#endif } #endif diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index f03305ae7..5b7f106f3 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -285,6 +285,13 @@ + + + + + + + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 31aa60c42..044cc3406 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -127,11 +127,10 @@ fog end factor = 1.0 num lights = 8 [Water] -# Enable this to get fancy-looking water with reflections and refractions -# Only available if object shaders are on -# All the settings below have no effect if this is false shader = false +refraction = false + rtt size = 512 reflect terrain = true reflect statics = false @@ -139,7 +138,6 @@ reflect small statics = false reflect actors = false reflect misc = false -# Enable underwater effect. It is not resource intensive, so only disable it if you have problems. underwater effect = false [Sound]