diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 23d2223844..d0060c2430 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -109,6 +109,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); 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"); applyCompositors(); @@ -638,6 +639,7 @@ 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 (); } else if (it->second == "underwater effect" && it->first == "Water") diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 7bbe107ed2..a886eac93f 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -17,6 +17,7 @@ #include "compositors.hpp" #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -40,6 +41,8 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); + mMaterial = MaterialManager::getSingleton().getByName("Water"); + mTop = cell->water; mIsUnderwater = false; @@ -66,8 +69,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel applyRTT(); applyVisibilityMask(); - - createMaterial(); mWater->setMaterial(mMaterial); Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh"); @@ -84,6 +85,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel setHeight(mTop); + sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); + m->setListener (this); + // ---------------------------------------------------------------------------------------------- // ---------------------------------- reflection debug overlay ---------------------------------- @@ -106,7 +110,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); - TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(mReflectionTexture->getName()); + debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(mReflectionTexture->getName()); OverlayContainer* debugPanel; @@ -238,29 +242,6 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) } } -void Water::createMaterial() -{ - if (mReflectionTarget == 0) - { - mMaterial = MaterialManager::getSingleton().getByName("Water_Fallback"); - } - else - { - mMaterial = MaterialManager::getSingleton().getByName("Water"); - sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName()); - } - - // these have to be set in code - std::string textureNames[32]; - for (int i=0; i<32; ++i) - { - textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; - } - - if (mReflectionTarget == 0) - mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); -} - void Water::assignTextures() { if (Settings::Manager::getBool("shader", "Water")) @@ -292,7 +273,7 @@ void Water::updateVisible() void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) { // We don't want the sky to get clipped by custom near clip plane (the water plane) - if (((queueGroupId < 20) || queueGroupId == RQG_UnderWater) && mReflectionRenderActive) + if (queueGroupId < 20 && mReflectionRenderActive) { mOldFarClip = mReflectionCamera->getFarClipDistance (); mReflectionCamera->disableCustomNearClipPlane(); @@ -309,7 +290,7 @@ void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &in void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) { - if (((queueGroupId < 20) || queueGroupId == RQG_UnderWater) && mReflectionRenderActive) + if (queueGroupId < 20 && mReflectionRenderActive) { mReflectionCamera->setFarClipDistance (mOldFarClip); if (!mIsUnderwater) @@ -363,6 +344,8 @@ void Water::applyRTT() rtt->setActive(true); mReflectionTarget = rtt; + + sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName()); } } @@ -406,7 +389,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin { applyRTT(); applyVisibilityMask(); - createMaterial(); mWater->setMaterial(mMaterial); assignTextures(); } @@ -414,4 +396,27 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin applyVisibilityMask(); } +void Water::requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration) +{ +} + +void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& configuration) +{ + if (configuration == "local_map" || !Settings::Manager::getBool("shader", "Water")) + { + // for simple water, set animated texture names + // these have to be set in code + std::string textureNames[32]; + for (int i=0; i<32; ++i) + { + textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; + } + + Ogre::Technique* t = static_cast(m->getMaterial())->getOgreTechniqueForConfiguration(configuration); + t->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); + t->getPass(0)->setDepthWriteEnabled (false); + t->getPass(0)->setSceneBlending (Ogre::SBT_TRANSPARENT_ALPHA); + } +} + } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 6d0001119e..60e39c4966 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -13,6 +13,8 @@ #include "renderconst.hpp" +#include + namespace Ogre { class Camera; @@ -29,7 +31,7 @@ namespace MWRender { class RenderingManager; /// Water rendering - class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener + class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener, public sh::MaterialInstanceListener { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; @@ -74,7 +76,6 @@ namespace MWRender { std::string mCompositorName; - void createMaterial(); Ogre::MaterialPtr mMaterial; Ogre::Camera* mReflectionCamera; @@ -104,6 +105,9 @@ namespace MWRender { void changeCell(const ESM::Cell* cell); void setHeight(const float height); + virtual void requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration); + virtual void createdConfiguration (sh::MaterialInstance* m, const std::string& configuration); + }; } diff --git a/extern/shiny b/extern/shiny index 4853ea7351..7af50bf446 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit 4853ea7351edced75a48662da5f3e857961e0b47 +Subproject commit 7af50bf4463a828ee0e8cb72c93445c793864bf9 diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index cddf49a03d..ee97451d39 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -13,4 +13,5 @@ configuration local_map lighting false shadows false shadows_pssm false + simple_water true } diff --git a/files/materials/water.mat b/files/materials/water.mat index 2ae561d770..dcea5a0d07 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -2,6 +2,11 @@ material Water { pass { + emissive 0.6 0.7 1.0 + ambient 0 0 0 + diffuse 0 0 0 1 + specular 0 0 0 32 + vertex_program water_vertex fragment_program water_fragment @@ -29,6 +34,15 @@ material Water { direct_texture water_nm.png } + + + // for simple_water + texture_unit animatedTexture + { + create_in_ffp true + scale 0.1 0.1 + alpha_op_ex source1 src_manual src_current 0.7 + } } } diff --git a/files/materials/water.shader b/files/materials/water.shader index 4bfc324210..a5eb9b1896 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -1,7 +1,68 @@ #include "core.h" + +#define SIMPLE_WATER @shGlobalSettingBool(simple_water) + + +#if SIMPLE_WATER + // --------------------------------------- SIMPLE WATER --------------------------------------------------- + + + #define MRT @shGlobalSettingBool(mrt_output) + + +#ifdef SH_VERTEX_SHADER + + SH_BEGIN_PROGRAM + shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + shInput(float2, uv0) + shOutput(float2, UV) + shOutput(float, depth) + + SH_START_PROGRAM + { + shOutputPosition = shMatrixMult(wvp, shInputPosition); + UV = uv0; + depth = shOutputPosition.z; + } + +#else + + SH_BEGIN_PROGRAM + shSampler2D(animatedTexture) + shInput(float2, UV) + shInput(float, depth) +#if MRT + shDeclareMrtOutput(1) +#endif + + shUniform(float3, fogColor) @shAutoConstant(fogColor, fog_colour) + shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params) + + + SH_START_PROGRAM + { + shOutputColour(0).xyz = shSample(animatedTexture, UV * 15).xyz * float3(0.6, 0.7, 1.0); + shOutputColour(0).w = 0.7; + + float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); + +#if MRT + shOutputColour(1) = float4(1,1,1,1); +#endif + } + +#endif + +#else + + + // Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html ) + + #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -241,3 +302,6 @@ } #endif + + +#endif diff --git a/files/water/water.material b/files/water/water.material deleted file mode 100644 index 7376d10cc9..0000000000 --- a/files/water/water.material +++ /dev/null @@ -1,221 +0,0 @@ -vertex_program UnderwaterEffectVP cg -{ - source underwater.cg - entry_point main_vp - profiles vs_1_1 arbvp1 - - default_params - { - param_named_auto worldViewProj worldviewproj_matrix - } -} - - -fragment_program UnderwaterEffectFP_NoMRT cg -{ - source underwater.cg - entry_point main_fp_nomrt - profiles ps_2_0 arbfp1 -} - -fragment_program UnderwaterEffectFP cg -{ - source underwater.cg - entry_point main_fp - profiles ps_2_0 arbfp1 -} - -vertex_program Water_VP cg -{ - source water.cg - entry_point main_vp - profiles vs_2_x arbvp1 - - default_params - { - param_named_auto wvpMat worldviewproj_matrix - } -} - -fragment_program Water_FP cg -{ - source water.cg - entry_point main_fp - profiles ps_2_x arbfp1 -} - -material __Water -{ - technique - { - pass - { - cull_hardware none - - vertex_program_ref Water_VP - { - param_named_auto camPosObjSpace camera_position_object_space - } - fragment_program_ref Water_FP - { - param_named_auto time time 0.1 - //param_named_auto fogColour fog_colour - //param_named_auto fogParams fog_params - param_named_auto renderTargetFlipping render_target_flipping - param_named_auto far far_clip_distance - param_named_auto lightPosObjSpace0 light_position_object_space 0 - param_named_auto lightSpecularColour0 light_specular_colour 0 - param_named isUnderwater float 0 - } - - texture_unit reflectionMap - { - texture WaterReflection - tex_address_mode clamp - } - - texture_unit refractionMap - { - tex_address_mode clamp - } - - texture_unit depthMap - { - tex_address_mode clamp - } - - texture_unit normalMap - { - texture WaterNormal2.tga - } - } - } - - technique - { - scheme Fallback - pass - { - cull_hardware none - scene_blend alpha_blend - depth_write off - diffuse 0 0 0 1 - emissive 0.6 0.7 1.0 - ambient 0 0 0 - texture_unit - { - // texture names set via code - scale 0.1 0.1 - alpha_op_ex source1 src_manual src_current 0.7 - } - } - } - -} - -material Water_Fallback -{ - technique - { - scheme Fallback - pass - { - cull_hardware none - scene_blend alpha_blend - depth_write off - diffuse 0 0 0 1 - emissive 0.6 0.7 1.0 - ambient 0 0 0 - texture_unit - { - // texture names set via code - scale 0.1 0.1 - alpha_op_ex source1 src_manual src_current 0.7 - } - } - } -} - -material Water/CompositorNoMRT -{ - technique - { - pass - { - depth_check off - vertex_program_ref UnderwaterEffectVP - { - param_named_auto timeVal time 0.25 - param_named scale float 0.1 - } - - fragment_program_ref UnderwaterEffectFP_NoMRT - { - } - - texture_unit RT - { - tex_coord_set 0 - tex_address_mode clamp - filtering linear linear linear - } - - texture_unit - { - texture WaterNormal2.tga 2d - tex_coord_set 1 - //tex_address_mode clamp - filtering linear linear linear - } - texture_unit - { - texture caustic_0.png 2d - tex_coord_set 2 - //tex_address_mode clamp - filtering linear linear linear - } - } - } -} - -material Water/Compositor -{ - technique - { - pass - { - depth_check off - vertex_program_ref UnderwaterEffectVP - { - param_named_auto timeVal time 0.25 - param_named scale float 0.1 - } - - fragment_program_ref UnderwaterEffectFP - { - param_named_auto far far_clip_distance - } - - texture_unit RT - { - tex_coord_set 0 - tex_address_mode clamp - } - - texture_unit - { - texture WaterNormal2.tga 2d - tex_coord_set 2 - } - texture_unit - { - texture caustic_0.png 2d - tex_coord_set 3 - } - - texture_unit DepthMap - { - } - } - } -}