From d42cf2854a0db9980d5506cd2ef961ca0ea93eb3 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Sun, 7 Sep 2025 21:15:00 +0300 Subject: [PATCH] Watergit push! --- CMakeLists.txt | 2 + src/gamedata/GUIModule.cpp | 9 +- src/gamedata/GUIModule.h | 7 ++ src/gamedata/GameData.cpp | 2 +- src/gamedata/WaterModule.cpp | 196 ++++++++++++++++++++++++++++++++--- src/gamedata/WaterModule.h | 17 ++- water/depth.frag | 5 +- water/water.frag | 82 ++++++++++++++- water/water.material | 25 ++++- water/water.program | 35 ++++++- water/water.vert | 52 ++++++++-- 11 files changed, 388 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cdc3b6..374c148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,6 +242,8 @@ set(WATER_SRC water.program water.frag water.vert + depth.frag + depth.vert water.compositor waves2.png ) diff --git a/src/gamedata/GUIModule.cpp b/src/gamedata/GUIModule.cpp index 2a994c7..cdfd0c6 100644 --- a/src/gamedata/GUIModule.cpp +++ b/src/gamedata/GUIModule.cpp @@ -41,11 +41,8 @@ struct GUIListener : public Ogre::RenderTargetListener { // ECS::get().get().app->setWindowGrab(true); if (ImGui::Button("Shitty Quit button")) Ogre::Root::getSingleton().queueEndRendering(); - if (ImGui::Button("Chick-chick")) { - ECS::get().get_mut().enabled = false; - ECS::get().modified(); - // ECS::get().get().app->setWindowGrab(true); - } + if (ImGui::Button("Chick-chick")) + ECS::get().get().finish(); ImGui::Text("We do stoopid..."); ImGui::End(); } @@ -74,7 +71,7 @@ struct GUIListener : public Ogre::RenderTargetListener { Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0)); pnode->setOrientation(nq); - // ECS::get().get().app->setWindowGrab(true); + ECS::get().get().finish(); } void buildings_editor() { diff --git a/src/gamedata/GUIModule.h b/src/gamedata/GUIModule.h index 33341d7..e0429e7 100644 --- a/src/gamedata/GUIModule.h +++ b/src/gamedata/GUIModule.h @@ -21,6 +21,13 @@ struct GUI { ECS::get().modified(); } } + static void finish() + { + ECS::GUI &gui = ECS::get().get_mut(); + gui.enabled = false; + ECS::get().modified(); + setWindowGrab(true); + } }; struct GUIModule { flecs::entity ui_wait; diff --git a/src/gamedata/GameData.cpp b/src/gamedata/GameData.cpp index dd9ec31..e21840b 100644 --- a/src/gamedata/GameData.cpp +++ b/src/gamedata/GameData.cpp @@ -35,7 +35,7 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world, ecs.set({ cameraNode, camera, false }); ecs.add(); ecs.add(); - ecs.set({ nullptr, nullptr, nullptr }); + ecs.set({ nullptr, nullptr, nullptr, nullptr, nullptr }); ecs.set({ nullptr }); ecs.set({ nullptr, nullptr, diff --git a/src/gamedata/WaterModule.cpp b/src/gamedata/WaterModule.cpp index bd14dde..12eb8ad 100644 --- a/src/gamedata/WaterModule.cpp +++ b/src/gamedata/WaterModule.cpp @@ -22,6 +22,16 @@ WaterModule::WaterModule(flecs::world &ecs) float delta = eng.delta; if (!water.mWaterEnt || !water.mWaterNode) { std::cout << "Water setup\n"; + water.mDepthMaterial = + Ogre::MaterialManager::getSingleton() + .getByName("Water/Depth"); + OgreAssert(water.mDepthMaterial, + "Water Depth material not found."); + water.mDepthMaterial->load(); + water.mDepthTech = + water.mDepthMaterial->getBestTechnique(); + OgreAssert(water.mDepthTech, + "Bad material technique"); water.mAbove = false; water.mInRefTexUpdate = false; water.mRenderTargetListener.mSurface = &water; @@ -31,19 +41,16 @@ WaterModule::WaterModule(flecs::world &ecs) Ogre::Plane(Ogre::Vector3::UNIT_Y, 0); water.mReflectionPlane = Ogre::Plane( Ogre::Vector3(0.0, 1.0, 0.0), - 0.0f /* water height */); + 0.5f /* water height */); + float h = 0.0f; water.mReflectionClipPlaneAbove = Ogre::Plane( - Ogre::Vector3(0.0, 1.0, 0.0), - 0.0f /* water height */ - 2.0f); + Ogre::Vector3(0.0, 1.0, 0.0), -h); water.mReflectionClipPlaneBelow = Ogre::Plane( - Ogre::Vector3(0.0, -1.0, 0.0), - -(0.0f /* water height */ + 2.0)); + Ogre::Vector3(0.0, -1.0, 0.0), h); water.mRefractionClipPlaneAbove = Ogre::Plane( - Ogre::Vector3(0.0, -1.0, 0.0), - -(0.0f /* water height */ + 2.0)); + Ogre::Vector3(0.0, -1.0, 0.0), h); water.mRefractionClipPlaneBelow = Ogre::Plane( - Ogre::Vector3(0.0, 1.0, 0.0), - 0.0f /* water height */ - 2.0); + Ogre::Vector3(0.0, 1.0, 0.0), -h); #if 0 if (Ogre::TextureManager::getSingleton() .resourceExists(renderTargetName)) @@ -58,6 +65,58 @@ WaterModule::WaterModule(flecs::world &ecs) Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8A8, Ogre::TU_RENDERTARGET); + Ogre::MaterialPtr debug_mat = + Ogre::MaterialManager::getSingleton() + .getByName("Water/Debug", + "Water"); + if (!debug_mat) { + debug_mat = + Ogre::MaterialManager::getSingleton() + .create("Water/Debug", + "Water"); + Ogre::Technique *tech = + debug_mat->getTechnique(0); + Ogre::Pass *pass = tech->getPass(0); + pass->setLightingEnabled(false); + pass->setAmbient( + Ogre::ColourValue(1, 1, 1, 1)); + pass->setDiffuse(Ogre::ColourValue( + 0.0f, 0.2f, 0.5f, 1.0f)); + pass->setDepthCheckEnabled(false); + pass->setDepthWriteEnabled(false); + pass->setAlphaRejectFunction( + Ogre::CMPF_ALWAYS_PASS); + pass->setCullingMode(Ogre::CULL_NONE); + pass->setManualCullingMode( + Ogre::MANUAL_CULL_NONE); + Ogre::TextureUnitState *texture_unit = + pass->createTextureUnitState(); + texture_unit->setTextureName( + "ReflectionRefractionTexture"); + Ogre::Sampler::UVWAddressingMode uvw; + uvw.u = Ogre::TextureUnitState::TAM_MIRROR; + uvw.v = Ogre::TextureUnitState::TAM_MIRROR; + uvw.w = Ogre::TextureUnitState::TAM_MIRROR; + texture_unit->setTextureAddressingMode( + uvw); + texture_unit->setTextureFiltering( + Ogre::FT_MIN, Ogre::FO_LINEAR); + texture_unit->setTextureFiltering( + Ogre::FT_MAG, Ogre::FO_LINEAR); + texture_unit->setTextureFiltering( + Ogre::FT_MIP, Ogre::FO_LINEAR); + } + // create a frosted screen in front of the camera, using our dynamic texture to "thaw" certain areas + Ogre::Entity *ent = eng.mScnMgr->createEntity( + "WaterDebugPlane", + Ogre::SceneManager::PT_PLANE); + ent->setMaterialName("Water/Debug", "Water"); + ent->setVisibilityFlags(WATER_MASK); + Ogre::SceneNode *node = + camera.mCameraNode + ->createChildSceneNode(); + node->setPosition(-150, 60, -400); + node->attachObject(ent); water.mReflectionTexture = reflectionTexture->getBuffer() @@ -163,6 +222,18 @@ WaterModule::WaterModule(flecs::world &ecs) Ogre::FT_MAG, Ogre::FO_LINEAR); texture_unit->setTextureFiltering( Ogre::FT_MIP, Ogre::FO_LINEAR); + Ogre::TextureUnitState *texture_unit2 = + pass->createTextureUnitState(); + texture_unit2->setTextureName( + "waves2.png"); + texture_unit2->setTextureAddressingMode( + uvw); + texture_unit2->setTextureFiltering( + Ogre::FT_MIN, Ogre::FO_LINEAR); + texture_unit2->setTextureFiltering( + Ogre::FT_MAG, Ogre::FO_LINEAR); + texture_unit2->setTextureFiltering( + Ogre::FT_MIP, Ogre::FO_NONE); #if 0 bool success = Ogre::RTShader::ShaderGenerator::getSingletonPtr() @@ -220,8 +291,19 @@ WaterModule::WaterModule(flecs::world &ecs) water.mReflectionCamera = eng.mScnMgr->createCamera( "ReflectionCamera"); - camera.mCamera->getParentSceneNode() - ->attachObject(water.mReflectionCamera); + water.mReflectionDepthCamera = + eng.mScnMgr->createCamera( + "ReflectionDepthCamera"); + water.mReflectionCameraNode = + camera.mCamera->getParentSceneNode() + ->createChildSceneNode( + "ReflectionCameraNode"); + water.mReflectionCameraNode->setPosition( + Ogre::Vector3(0, 1.0f, 0)); + water.mReflectionCameraNode->attachObject( + water.mReflectionCamera); + water.mReflectionCameraNode->attachObject( + water.mReflectionDepthCamera); water.mReflectionCamera->setAspectRatio( camera.mCamera->getAspectRatio()); water.mReflectionCamera->setNearClipDistance( @@ -234,23 +316,62 @@ WaterModule::WaterModule(flecs::world &ecs) water.mReflectionCamera->enableReflection( water.mReflectionPlane); + water.mReflectionDepthCamera->setAspectRatio( + camera.mCamera->getAspectRatio()); + water.mReflectionDepthCamera->setNearClipDistance( + camera.mCamera->getNearClipDistance()); + water.mReflectionDepthCamera->setFarClipDistance( + camera.mCamera->getFarClipDistance()); + water.mReflectionDepthCamera + ->enableCustomNearClipPlane( + water.mReflectionClipPlaneAbove); + water.mReflectionDepthCamera->enableReflection( + water.mReflectionPlane); + Ogre::Viewport *reflectionViewport = water.mReflectionTexture->addViewport( water.mReflectionCamera, 0, 0, - 0, 0.5f, 1.0f); + 0, 0.5f, 0.5f); reflectionViewport->setClearEveryFrame(true); reflectionViewport->setBackgroundColour( Ogre::ColourValue(0.0, 0.0, 1.0, 1.0)); reflectionViewport->setOverlaysEnabled(false); reflectionViewport->setSkiesEnabled(true); reflectionViewport->setAutoUpdated(false); + reflectionViewport->setVisibilityMask( + ~WATER_MASK); water.mViewports[0] = reflectionViewport; + Ogre::Viewport *reflectionDepthViewport = + water.mReflectionTexture->addViewport( + water.mReflectionDepthCamera, 2, + 0, 0.5f, 0.5f, 0.5f); + reflectionDepthViewport->setClearEveryFrame( + true); + reflectionDepthViewport->setBackgroundColour( + Ogre::ColourValue(0.0, 0.0, 0.0, 0.0)); + reflectionDepthViewport->setOverlaysEnabled( + false); + reflectionDepthViewport->setSkiesEnabled(true); + reflectionDepthViewport->setAutoUpdated(false); + reflectionDepthViewport->setVisibilityMask( + ~WATER_MASK); + water.mViewports[2] = reflectionDepthViewport; + water.mRefractionCamera = eng.mScnMgr->createCamera( "RefractionCamera"); - camera.mCamera->getParentSceneNode() - ->attachObject(water.mRefractionCamera); + water.mRefractionDepthCamera = + eng.mScnMgr->createCamera( + "RefractionDepthCamera"); + water.mRefractionCameraNode = + camera.mCamera->getParentSceneNode() + ->createChildSceneNode( + "RefractionCameraNode"); + water.mRefractionCameraNode->attachObject( + water.mRefractionCamera); + water.mRefractionCameraNode->attachObject( + water.mRefractionDepthCamera); water.mRefractionCamera->setAspectRatio( camera.mCamera->getAspectRatio()); water.mRefractionCamera->setNearClipDistance( @@ -261,17 +382,50 @@ WaterModule::WaterModule(flecs::world &ecs) ->enableCustomNearClipPlane( water.mRefractionClipPlaneAbove); + water.mRefractionDepthCamera->setAspectRatio( + camera.mCamera->getAspectRatio()); + water.mRefractionDepthCamera->setNearClipDistance( + camera.mCamera->getNearClipDistance()); + water.mRefractionDepthCamera->setFarClipDistance( + camera.mCamera->getFarClipDistance()); + water.mRefractionDepthCamera + ->enableCustomNearClipPlane( + water.mRefractionClipPlaneAbove); + Ogre::Viewport *refractionViewport = water.mReflectionTexture->addViewport( water.mRefractionCamera, 1, 0.5, - 0, 0.5f, 1.0f); + 0, 0.5f, 0.5f); refractionViewport->setClearEveryFrame(true); refractionViewport->setBackgroundColour( Ogre::ColourValue(0.0, 0.5, 1.0, 1.0)); refractionViewport->setOverlaysEnabled(false); refractionViewport->setSkiesEnabled(false); refractionViewport->setAutoUpdated(false); + refractionViewport->setVisibilityMask( + ~WATER_MASK); water.mViewports[1] = refractionViewport; + + Ogre::Viewport *refractionDepthViewport = + water.mReflectionTexture->addViewport( + water.mRefractionDepthCamera, 3, + 0.5, 0.5, 0.5f, 0.5f); + refractionDepthViewport->setClearEveryFrame( + true); + refractionDepthViewport->setBackgroundColour( + Ogre::ColourValue(0.0, 0.0, 0.0, 0.0)); + refractionDepthViewport->setOverlaysEnabled( + false); + refractionDepthViewport->setSkiesEnabled(false); + refractionDepthViewport->setAutoUpdated(false); + refractionDepthViewport->setVisibilityMask( + ~WATER_MASK); + water.mViewports[3] = refractionDepthViewport; + + water.mRenderTargetListener.mInDepth = false; + eng.mScnMgr->getRenderQueue() + ->setRenderableListener( + &water.mRenderTargetListener); std::cout << "Water setup done\n"; } Ogre::Vector3 mCameraPos = @@ -290,6 +444,10 @@ WaterModule::WaterModule(flecs::world &ecs) water.mWaterEnt->setVisible(false); water.mViewports[0]->update(); water.mViewports[1]->update(); + water.mRenderTargetListener.mInDepth = true; + water.mViewports[2]->update(); + water.mViewports[3]->update(); + water.mRenderTargetListener.mInDepth = false; water.mWaterEnt->setVisible(true); }); ecs.system( @@ -465,4 +623,12 @@ void WaterSurface::RenderTextureListener::postRenderTargetUpdate( mSurface->mWaterEnt->setVisible(true); mSurface->mInRefTexUpdate = false; } +bool WaterSurface::RenderTextureListener::renderableQueued( + Ogre::Renderable *rend, Ogre::uint8 groupID, ushort priority, + Ogre::Technique **ppTech, Ogre::RenderQueue *pQueue) +{ + if (mInDepth) + *ppTech = mSurface->mDepthTech; + return true; +} } \ No newline at end of file diff --git a/src/gamedata/WaterModule.h b/src/gamedata/WaterModule.h index 447a536..af79175 100644 --- a/src/gamedata/WaterModule.h +++ b/src/gamedata/WaterModule.h @@ -9,20 +9,33 @@ struct WaterSurface { Ogre::Entity *mWaterEnt; Ogre::RenderTexture *mReflectionTexture; Ogre::Camera *mReflectionCamera, *mRefractionCamera; + Ogre::SceneNode *mReflectionCameraNode, *mRefractionCameraNode; + Ogre::Camera *mReflectionDepthCamera; + Ogre::Camera *mRefractionDepthCamera; + Ogre::RenderTargetListener *mTargetListener; + Ogre::MaterialPtr mDepthMaterial; + Ogre::Technique *mDepthTech; bool mInRefTexUpdate; bool mAbove; - struct RenderTextureListener : public Ogre::RenderTargetListener { + struct RenderTextureListener + : public Ogre::RenderTargetListener, + public Ogre::RenderQueue::RenderableListener { WaterSurface *mSurface; + bool mInDepth; void preRenderTargetUpdate( const Ogre::RenderTargetEvent &evt) override; void postRenderTargetUpdate( const Ogre::RenderTargetEvent &evt) override; + bool renderableQueued(Ogre::Renderable *rend, + Ogre::uint8 groupID, ushort priority, + Ogre::Technique **ppTech, + Ogre::RenderQueue *pQueue); }; RenderTextureListener mRenderTargetListener; Ogre::Plane mWaterPlane, mReflectionPlane, mReflectionClipPlaneAbove, mReflectionClipPlaneBelow, mRefractionClipPlaneAbove, mRefractionClipPlaneBelow; - Ogre::Viewport *mViewports[2]; + Ogre::Viewport *mViewports[4]; }; struct WaterBody { btPairCachingGhostObject *mWaterBody; diff --git a/water/depth.frag b/water/depth.frag index 08ecad4..d7bf76d 100644 --- a/water/depth.frag +++ b/water/depth.frag @@ -9,6 +9,7 @@ IN(vec4 position, POSITION) IN(vec3 positionWS, TEXCOORD0) MAIN_DECLARATION { - vec4 depth = vec4(length(positionWS - cameraPosition), 0.0, 0.0, 1.0); - gl_FragColor = depth; + highp float depth = length(positionWS - cameraPosition); + vec4 depthv = vec4(depth / 256.0, depth / 500.0, depth / 1000.0, 1.0); + gl_FragColor = depthv; } diff --git a/water/water.frag b/water/water.frag index f183de5..a77ff40 100644 --- a/water/water.frag +++ b/water/water.frag @@ -1,12 +1,29 @@ OGRE_NATIVE_GLSL_VERSION_DIRECTIVE #include -// SAMPLER2D(noiseMap, 0); SAMPLER2D(reflectMap, 0); +SAMPLER2D(noiseMap, 1); // SAMPLER2D(refractMap, 1); +#if NEW_WATER_SHADER +MAIN_PARAMETERS +IN(vec4 clipSpace, TEXCOORD0) +MAIN_DECLARATION +{ + // vec2 ndc = gl_FragCoord.xy / viewportSize.xy; + vec2 ndc = clipSpace.xy / clipSpace.w / 2.0 + vec2(0.5, 0.5); + vec2 reflectionUV = vec2(ndc.x, 1.0 - ndc.y) * 0.5; + vec2 refractionUV = vec2(ndc.x, 1.0 - ndc.y) * 0.5 + vec2(0.5, 0.0); + vec4 reflectionColour = texture2D(reflectMap, reflectionUV); + vec4 refractionColour = texture2D(reflectMap, refractionUV); + gl_FragColor = mix(reflectionColour, refractionColour, 0.5); +} +#else OGRE_UNIFORMS( uniform float renderTargetFlipping; uniform vec4 viewportSize; uniform f32vec4 cameraPosition; +uniform mat4 viewProj2; +uniform float time2; +uniform vec4 materialVariables; ) float rand(float n){return fract(sin(n) * 43758.5453123);} float rand2(vec2 n) { @@ -26,6 +43,11 @@ float noise(vec2 n) { MAIN_PARAMETERS IN(f32vec3 positionWS, TEXCOORD0) IN(f32vec3 vnormal, TEXCOORD1) +IN(f32vec3 viewDirection, TEXCOORD2) +IN(f32vec3 viewDirectionTS, TEXCOORD3) +IN(f32vec3 olightDirection, TEXCOORD4) +IN(f32vec3 lightDirectionTS, TEXCOORD5) +IN(vec2 bumpCoord0, TEXCOORD6) MAIN_DECLARATION { float flip = -renderTargetFlipping; @@ -37,14 +59,68 @@ MAIN_DECLARATION screenUV.y = screenUV.y * 0.6 + 0.2; #endif + vec2 texCoord = 0.001 * positionWS.xz; + vec3 normal = vec3_splat(0.0); + float time = time2 * 0.01; + f32vec2 muv = screenUV * 1.1 + vec2(-0.1, -0.1); + normal += normalize(2.0 * texture2D(noiseMap, vec2(texCoord.x, texCoord.y - 5.0 * time)).rgb - 1.0); + normal += normalize(2.0 * texture2D(noiseMap, vec2(texCoord.y, 1.0 - texCoord.x - 5.0 * time)).rgb - 1.0); + normal += normalize(2.0 * texture2D(noiseMap, vec2(1.0 - texCoord.x, 1.0 - texCoord.y - 5.0 * time)).rgb - 1.0); + normal += normalize(2.0 * texture2D(noiseMap, vec2(1.0 - texCoord.y, texCoord.x - 5.0 * time)).rgb - 1.0); + normal = normalize(normal); + float reflectionDepth = 0.08; + float refractionDepth = 1.05; + + vec2 reflectionTexCoord = screenUV + (normal.xy * reflectionDepth) / length(positionWS - cameraPosition.xyz); + vec2 refractionTexCoord = screenUV + normal.xy * refractionDepth; + float depth = saturate(length(positionWS - cameraPosition.xyz) * 0.01); float nx = sin(noise(vec2(1300.0 + screenUV.x * 48.11, 1100.0 + screenUV.y))); float ny = sin(noise(vec2(100.0 + screenUV.y * 72.2, 1500.0 + screenUV.x))); - vec4 reflectionColour = texture2D(reflectMap, vec2(nx, ny) + screenUV * vec2(0.5, 1.0)); - vec4 refractionColour = texture2D(reflectMap, vec2(nx, ny) + screenUV * vec2(0.5, 1.0) + vec2(0.5, 0.0)); + vec4 t0 = texture2D(noiseMap, bumpCoord0) * 2.0 - 1.0; + vec4 t1 = texture2D(noiseMap, bumpCoord0 + vec2(0.75, 0.02)) * 2.0 - 1.0; + vec4 t2 = texture2D(noiseMap, bumpCoord0 + vec2(0.33, 0.11)) * 2.0 - 1.0; + vec4 N = vec4(t0.xyz + t1.xyz + t2.xyz, 1); + N = normalize(viewProj2 * N) * 0.1; + vec4 mrow = vec4(screenUV.x, 0, screenUV.y, 1); + vec4 mrowt = mul(viewProj2, mrow); + f32vec2 e = vec2(0, 0); + float min_speed = 16.0; + float max_ax = 0.01; + float max_ay = 0.005; + float px = noise(vec2(screenUV.x * 13123.0, screenUV.y * 1121.0)); + float py = noise(vec2(screenUV.y * 15123.0, screenUV.x * 1421.0)); + float offsetx = 0.0; + float offsety = 0.0; + float l = length(positionWS - cameraPosition.xyz); + for (int i = 0; i < 4; i++) { + e.x += sin(mrow.z * min_speed + offsetx + time2 * 0.01) * max_ax * (1.0 + 1.0 / (1.0 + l * 30.0)); + e.y += cos(mrow.x * min_speed + offsety + time2 * 0.01) * max_ay; + offsetx += 113.0; + offsety += 78.0; + min_speed *= 2.45; + max_ax *= 0.9; + max_ay *= 0.9; + } + f32vec2 reflectUV = /* screenUV + e */ reflectionTexCoord; + f32vec2 refractUV = /* screenUV + e */ refractionTexCoord; + reflectUV.x = (reflectUV.x < 0.05 ) ? 0.05 : reflectUV.x; + reflectUV.x = (reflectUV.x > 0.95 ) ? 0.95 : reflectUV.x; + f32vec2 uv_mul = vec2(0.5, 1.0); + f32vec2 uv_offset = vec2(0.5, 0.0); + vec4 reflectionColour = texture2D(reflectMap, reflectUV * uv_mul); + vec4 refractionColour = texture2D(reflectMap, refractUV * uv_mul + uv_offset); + if (reflectionColour.a == 0.0) { + reflectionColour = texture2D(reflectMap, screenUV * uv_mul); + } + if (refractionColour.a == 0.0) { + refractionColour = texture2D(reflectMap, screenUV * uv_mul + uv_offset); + } + vec4 result = mix(mix(reflectionColour, refractionColour, 0.5), vec4(0.0, 1.0, 1.0, 1.0), depth); float mul = dot(vec3(0.0, 1.0, 0.0), vnormal); result = result * mul; result.a = 1.0; gl_FragColor = result; } +#endif \ No newline at end of file diff --git a/water/water.material b/water/water.material index 2783272..533b050 100644 --- a/water/water.material +++ b/water/water.material @@ -58,10 +58,29 @@ material Water/Below } } rtshader_system - { + { // Override lighting stage with per pixel lighting. lighting_stage per_pixel - } + } } */ - +material Water/Depth +{ + technique + { + pass + { + cull_hardware none + alpha_rejection greater_equal 0.5 + vertex_program_ref Water/depth_vp + { + param_named_auto world world_matrix + param_named_auto worldViewProj worldviewproj_matrix + } + fragment_program_ref Water/depth_fp + { + param_named_auto cameraPosition camera_position + } + } + } +} diff --git a/water/water.program b/water/water.program index d76e59d..fdd227e 100644 --- a/water/water.program +++ b/water/water.program @@ -17,6 +17,7 @@ fragment_program Water/depth_fp glsl glsles glslang hlsl } } +/* fragment_program Water/water_fp glsl glsles glslang hlsl { source water.frag @@ -24,10 +25,12 @@ fragment_program Water/water_fp glsl glsles glslang hlsl { param_named_auto renderTargetFlipping render_target_flipping param_named_auto cameraPosition camera_position + param_named_auto viewProj2 viewproj_matrix // param_named_auto ambient surface_ambient_colour // param_named_auto diffuse surface_diffuse_colour param_named_auto viewportSize viewport_size -//// param_named_auto time time +// param_named_auto time2 time + param_named_auto time2 time_0_x 100.0 //// param_named NormalMap int 0 //// param_named EnvironmentMap int 1 // param_named deepColor float4 0 0.2 0.5 1.0 @@ -47,9 +50,11 @@ fragment_program Water/water_fp glsl glsles glslang hlsl // param_named hdrMultiplier float 0.471 // param_named tintColour float4 0 0.05 0.05 1 // param_named noiseScale float 0.03 -//// param_named noiseMap int 0 param_named reflectMap int 0 + param_named noiseMap int 1 //// param_named refractMap int 1 + param_named_auto materialVariables custom 1 + preprocessor_defines NEW_WATER_SHADER } } @@ -68,12 +73,36 @@ vertex_program Water/water_vp glsl glsles glslang hlsl param_named BumpScale float 0.2 param_named textureScale float2 25 26 param_named bumpSpeed float2 0.015 0.005 - param_named_auto time time_0_x 100.0 + param_named_auto time time_0_x 100.0 param_named waveFreq float 0.5 param_named waveAmp float 1.0 + param_named_auto cameraPositionOS camera_position_object_space + param_named_auto lightDirection light_direction_object_space 0 param_named scroll float 1 param_named scale float 1 param_named noise float 1 + preprocessor_defines NEW_WATER_SHADER } } + */ +fragment_program Water/water_fp glsl glsles glslang hlsl +{ + source water.frag + default_params + { + } + preprocessor_defines NEW_WATER_SHADER +} + +vertex_program Water/water_vp glsl glsles glslang hlsl +{ + source water.vert + default_params + { + param_named_auto projectionMatrix projection_matrix + param_named_auto viewMatrix view_matrix + param_named_auto modelMatrix world_matrix + } + preprocessor_defines NEW_WATER_SHADER +} diff --git a/water/water.vert b/water/water.vert index 3448d8a..8e8bf9b 100644 --- a/water/water.vert +++ b/water/water.vert @@ -22,6 +22,22 @@ Comments: OGRE_NATIVE_GLSL_VERSION_DIRECTIVE #include +#if NEW_WATER_SHADER +OGRE_UNIFORMS( +uniform mat4 projectionMatrix; +uniform mat4 viewMatrix; +uniform mat4 modelMatrix; +) +MAIN_PARAMETERS +IN(vec4 position, POSITION) +OUT(vec4 clipSpace, TEXCOORD0) +MAIN_DECLARATION +{ + clipSpace = projectionMatrix * viewMatrix * modelMatrix * vec4(position.xyz, 1.0); + gl_Position = clipSpace; +} + +#else OGRE_UNIFORMS( uniform vec3 eyePosition; uniform float BumpScale; @@ -30,12 +46,14 @@ uniform vec2 bumpSpeed; uniform highp float time; uniform float waveFreq; uniform float waveAmp; +uniform vec4 cameraPositionOS; uniform mat4 world; uniform mat4 viewProj; uniform mat4 worldView; uniform mat4 worldViewProj; uniform mat4 textureProjMatrix; uniform mat3 normalMatrix; +uniform vec3 lightDirection; uniform float scale; // the amount to scale the noise texture by uniform float scroll; // the amount by which to scroll the noise uniform float noise; // the noise perturb as a factor of the time @@ -89,30 +107,46 @@ vec4 wave2(vec4 parameter, vec2 position, float t, inout vec3 tangent, inout vec MAIN_PARAMETERS IN(vec4 vertex, POSITION) IN(vec3 normal, NORMAL) +IN(vec3 tangent, TANGENT) +IN(vec4 uv0, TEXCOORD0) OUT(f32vec3 positionWS, TEXCOORD0) OUT(f32vec3 vnormal, TEXCOORD1) -OUT(f32vec3 vbinormal, TEXCOORD2) -OUT(f32vec3 vtangent, TEXCOORD3) -OUT(float vertex_height, TEXCOORD4) +OUT(f32vec3 viewDirection, TEXCOORD2) +OUT(f32vec3 viewDirectionTS, TEXCOORD3) +OUT(f32vec3 olightDirection, TEXCOORD4) +// OUT(f32vec3 vbinormal, TEXCOORD2) +// OUT(f32vec3 vtangent, TEXCOORD3) +// OUT(float vertex_height, TEXCOORD4) +OUT(f32vec3 lightDirectionTS, TEXCOORD5) +OUT(f32vec2 bumpCoord0, TEXCOORD6) MAIN_DECLARATION { + float textureScale = 0.6; + float bumpSpeed = 0.8; f32vec4 position = vec4(mul(world, vertex).xyz, 1.0); f32vec3 vertex_position = position.xyz; - f32vec3 tang = vec3(0.0, 0.0, 0.0); - f32vec3 bin = vec3(0.0, 0.0, 0.0); + f32vec3 tang = tangent; + f32vec3 bin = cross(tangent, normal); position += wave(wave_a, vertex_position.xz, time, tang, bin); position += wave(wave_b, vertex_position.xz, time, tang, bin); position += wave(wave_c, vertex_position.xz, time, tang, bin); position += wave(wave_d, vertex_position.xz, time, tang, bin); - vtangent = tang; - vbinormal = bin; - vertex_position = position.xyz; + // vtangent = tang; + // vbinormal = bin; + // vertex_position = position.xyz; // vnormal = normalize(mul(mat3(world), cross(vbinormal, vtangent))); - vnormal = normalize(cross(vbinormal, vtangent)); + vnormal = normalize(cross(bin, tang)); + mat3 TBN = mtxFromRows(tang, bin, vnormal); // vnormal = normalize(vec3(0.0, 1.0, 0.0)); // gl_Position = mul(worldViewProj, vertex); + viewDirection = vertex.xyz - cameraPositionOS.xyz; + viewDirectionTS = mul(TBN, viewDirection); + olightDirection = lightDirection; + lightDirectionTS = mul(TBN, lightDirection); gl_Position = mul(viewProj, position); positionWS = mul(world, vertex).xyz; + bumpCoord0.xy = uv0.xy * textureScale + time * bumpSpeed; } +#endif