actorid
scrawl 13 years ago
parent 9d7470e14c
commit e077814a8c

@ -261,7 +261,7 @@ int main(int argc, char**argv)
boost::filesystem::current_path(bundlePath);
#endif
//try
try
{
Files::ConfigurationManager cfgMgr;
OMW::Engine engine(cfgMgr);
@ -271,11 +271,11 @@ int main(int argc, char**argv)
engine.go();
}
}
/*catch (std::exception &e)
catch (std::exception &e)
{
std::cout << "\nERROR: " << e.what() << std::endl;
return 1;
}*/
}
return 0;
}

@ -209,7 +209,7 @@ namespace MWGui
mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1));
mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}");
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect objects", "Water") ? "#{sOn}" : "#{sOff}");
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}");
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");

@ -18,7 +18,7 @@ enum RenderQueueGroups
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_6,
RQG_UnderWater = Ogre::RENDER_QUEUE_7,
RQG_UnderWater = Ogre::RENDER_QUEUE_4,
RQG_Water = Ogre::RENDER_QUEUE_7+1,
@ -49,8 +49,8 @@ enum VisibilityFlags
RV_Sky = 64,
// Sun glare (not visible in reflection)
RV_Glare = 128,
// not visible in reflection
RV_NoReflection = 128,
RV_OcclusionQuery = 256,

@ -725,14 +725,9 @@ void RenderingManager::applyCompositors()
{
mCompositors->addCompositor("gbuffer", 0);
mCompositors->setCompositorEnabled("gbuffer", true);
mCompositors->addCompositor("Underwater", 1);
mCompositors->addCompositor("gbufferFinalizer", 2);
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
}
else
{
mCompositors->addCompositor("UnderwaterNoMRT", 0);
}
if (mWater)
mWater->assignTextures();

@ -307,7 +307,7 @@ void SkyManager::create()
mSun->setRenderQueue(RQG_SkiesEarly+4);
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode, "openmw_sun");
mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_Glare);
mSunGlare->setVisibilityFlags(RV_NoReflection);
// Stars
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
@ -389,7 +389,6 @@ void SkyManager::update(float duration)
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer)));
/// \todo improve this
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
@ -559,6 +558,10 @@ void SkyManager::setSunDirection(const Vector3& direction)
if (!mCreated) return;
mSun->setPosition(direction);
mSunGlare->setPosition(direction);
float height = direction.z;
float fade = ( height > 0.5) ? 1.0 : height * 2;
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(fade, height)));
}
void SkyManager::setMasserDirection(const Vector3& direction)
@ -607,6 +610,7 @@ void SkyManager::setLightningStrength(const float factor)
void SkyManager::setLightningDirection(const Ogre::Vector3& dir)
{
if (!mCreated) return;
mLightning->setDirection (dir);
}
@ -653,3 +657,10 @@ void SkyManager::scaleSky(float scale)
{
mRootNode->setScale(scale, scale, scale);
}
void SkyManager::setGlareEnabled (bool enabled)
{
if (!mCreated)
return;
mSunGlare->setVisible (mSunEnabled && enabled);
}

@ -164,6 +164,7 @@ namespace MWRender
void setLightningDirection(const Ogre::Vector3& dir);
void setGlare(const float glare);
void setGlareEnabled(bool enabled);
Ogre::Vector3 getRealSunPos();
void setSkyPosition(const Ogre::Vector3& position);

@ -28,7 +28,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend),
mOldFarClip(0),
mOldFarClip(0), mOldFarClip2(0),
mWaterTimer(0.f)
{
mSky = rend->getSkyManager();
@ -73,8 +73,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
underwaterDome->setRenderQueueGroup (RQG_UnderWater);
mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode ();
mUnderwaterDome->attachObject (underwaterDome);
mUnderwaterDome->setScale(100,100,100);
mUnderwaterDome->setScale(10000,10000,10000);
mUnderwaterDome->setVisible(false);
underwaterDome->setMaterialName("Underwater_Dome");
mSceneManager->addRenderQueueListener(this);
@ -162,7 +163,12 @@ void Water::changeCell(const ESM::Cell* cell)
void Water::setHeight(const float height)
{
mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Y, height);
// small error due to reflection texture size & reflection distortion
mErrorPlane = Plane(Vector3::UNIT_Y, height - 5);
mWaterNode->setPosition(0, height, 0);
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
}
@ -177,39 +183,16 @@ void Water::checkUnderwater(float y)
{
if (!mActive)
{
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
return;
}
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
{
//mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
// tell the shader we are not underwater
/*
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(0));
*/
mWater->setRenderQueueGroup(RQG_Water);
mIsUnderwater = false;
}
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
{
//if (mUnderwaterEffect)
//mRendering->getCompositors()->setCompositorEnabled(mCompositorName, true);
// tell the shader we are underwater
/*
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(1));
*/
//mWater->setRenderQueueGroup(RQG_UnderWater);
mIsUnderwater = true;
}
@ -308,24 +291,36 @@ 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 && mReflectionRenderActive)
if (((queueGroupId < 20) || queueGroupId == RQG_UnderWater) && mReflectionRenderActive)
{
mOldFarClip = mReflectionCamera->getFarClipDistance ();
mReflectionCamera->disableCustomNearClipPlane();
mReflectionCamera->setFarClipDistance (1000000000);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
else if (queueGroupId == RQG_UnderWater)
{/*
mOldFarClip2 = mCamera->getFarClipDistance ();
mCamera->setFarClipDistance (1000000000);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
*/}
}
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{
if (queueGroupId < 20 && mReflectionRenderActive)
if (((queueGroupId < 20) || queueGroupId == RQG_UnderWater) && mReflectionRenderActive)
{
mReflectionCamera->setFarClipDistance (mOldFarClip);
if (!mIsUnderwater)
mReflectionCamera->enableCustomNearClipPlane(mWaterPlane);
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
if (queueGroupId == RQG_UnderWater)
{
/*
mCamera->setFarClipDistance (mOldFarClip2);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
*/}
}
void Water::update(float dt)
@ -336,6 +331,8 @@ void Water::update(float dt)
mWaterTimer += dt;
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
}
void Water::applyRTT()
@ -366,8 +363,6 @@ void Water::applyRTT()
mReflectionTarget = rtt;
}
mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT";
}
void Water::applyVisibilityMask()

@ -36,6 +36,8 @@ namespace MWRender {
Ogre::SceneManager *mSceneManager;
Ogre::Plane mWaterPlane;
Ogre::Plane mErrorPlane;
Ogre::SceneNode *mWaterNode;
Ogre::Entity *mWater;
@ -47,6 +49,7 @@ namespace MWRender {
int mTop;
int mOldFarClip;
int mOldFarClip2;
float mWaterTimer;

@ -1,18 +0,0 @@
void RenderScene_vs(in float4 position : POSITION
,in float2 uv :TEXCOORD0
,uniform float4x4 wvp
,out float4 oPosition : POSITION
,out float2 oUV :TEXCOORD0)
{
oPosition = mul(wvp, position);
oUV = uv;
}
void RenderScene_ps(in float4 position : POSITION
,in float2 uv :TEXCOORD0
,uniform sampler2D tex1 : TEXUNIT0
,out float4 oColor : COLOR)
{
float4 scene =tex2D(tex1, uv);
oColor= scene;
}

@ -29,7 +29,7 @@ compositor gbuffer
pass render_quad
{
material RenderScene
material quad
input 0 mrt_output 0
}
}
@ -61,7 +61,7 @@ compositor gbufferFinalizer
}
pass render_quad
{
material RenderSceneNoDepth
material quad_noDepthWrite
input 0 previousscene
}
pass render_scene
@ -78,7 +78,7 @@ compositor gbufferFinalizer
}
pass render_quad
{
material RenderSceneNoDepth
material quad_noDepthWrite
input 0 no_mrt_output
}
}

@ -1,63 +0,0 @@
vertex_program RenderGBuffer_vs cg
{
source gbuffer.cg
profiles vs_4_0 vs_1_1 arbvp1
entry_point RenderScene_vs
default_params
{
param_named_auto wvp worldviewproj_matrix
}
}
fragment_program RenderGBuffer_ps cg
{
source gbuffer.cg
entry_point RenderScene_ps
profiles ps_4_0 ps_2_x arbfp1
default_params
{
}
}
material RenderScene
{
technique
{
pass
{
vertex_program_ref RenderGBuffer_vs
{
}
fragment_program_ref RenderGBuffer_ps
{
}
texture_unit tex1
{
//scenebuffer
}
}
}
}
material RenderSceneNoDepth
{
technique
{
pass
{
depth_write off
vertex_program_ref RenderGBuffer_vs
{
}
fragment_program_ref RenderGBuffer_ps
{
}
texture_unit tex1
{
//scenebuffer
}
}
}
}

@ -1,117 +0,0 @@
#define VISIBILITY 1500.0 // how far you can look through water
#define BIG_WAVES_X 0.3 // strength of big waves
#define BIG_WAVES_Y 0.3
#define MID_WAVES_X 0.3 // strength of middle sized waves
#define MID_WAVES_Y 0.15
#define SMALL_WAVES_X 0.15 // strength of small waves
#define SMALL_WAVES_Y 0.1
#define WAVE_CHOPPYNESS 0.15 // wave choppyness
#define WAVE_SCALE 0.01 // overall wave scale
#define ABBERATION 0.001 // chromatic abberation amount
float3 intercept(float3 lineP,
float3 lineN,
float3 planeN,
float planeD)
{
float distance = (planeD - dot(planeN, lineP)) / dot(lineN, planeN);
return lineP + lineN * distance;
}
float3 perturb1(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer)
{
float2 nCoord = float2(0.0);
bend *= WAVE_CHOPPYNESS;
nCoord = coords * (WAVE_SCALE * 0.05) + windDir * timer * (windSpeed*0.04);
float3 normal0 = 2.0 * shSample(tex, nCoord + float2(-timer*0.015,-timer*0.05)).rgb - 1.0;
nCoord = coords * (WAVE_SCALE * 0.1) + windDir * timer * (windSpeed*0.08)-normal0.xy*bend;
float3 normal1 = 2.0 * shSample(tex, nCoord + float2(+timer*0.020,+timer*0.015)).rgb - 1.0;
nCoord = coords * (WAVE_SCALE * 0.25) + windDir * timer * (windSpeed*0.07)-normal1.xy*bend;
float3 normal2 = 2.0 * shSample(tex, nCoord + float2(-timer*0.04,-timer*0.03)).rgb - 1.0;
nCoord = coords * (WAVE_SCALE * 0.5) + windDir * timer * (windSpeed*0.09)-normal2.xy*bend;
float3 normal3 = 2.0 * shSample(tex, nCoord + float2(+timer*0.03,+timer*0.04)).rgb - 1.0;
nCoord = coords * (WAVE_SCALE* 1.0) + windDir * timer * (windSpeed*0.4)-normal3.xy*bend;
float3 normal4 = 2.0 * shSample(tex, nCoord + float2(-timer*0.2,+timer*0.1)).rgb - 1.0;
nCoord = coords * (WAVE_SCALE * 2.0) + windDir * timer * (windSpeed*0.7)-normal4.xy*bend;
float3 normal5 = 2.0 * shSample(tex, nCoord + float2(+timer*0.1,-timer*0.06)).rgb - 1.0;
float3 normal = normalize(normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +
normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y +
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y);
return normal;
}
float3 perturb(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer)
{
bend *= WAVE_CHOPPYNESS;
float3 col = float3(0.0);
float2 nCoord = float2(0.0); //normal coords
nCoord = coords * (WAVE_SCALE * 0.025) + windDir * timer * (windSpeed*0.03);
col += shSample(tex,nCoord + float2(-timer*0.005,-timer*0.01)).rgb*0.20;
nCoord = coords * (WAVE_SCALE * 0.1) + windDir * timer * (windSpeed*0.05)-(col.xy/col.zz)*bend;
col += shSample(tex,nCoord + float2(+timer*0.01,+timer*0.005)).rgb*0.20;
nCoord = coords * (WAVE_SCALE * 0.2) + windDir * timer * (windSpeed*0.1)-(col.xy/col.zz)*bend;
col += shSample(tex,nCoord + float2(-timer*0.02,-timer*0.03)).rgb*0.20;
nCoord = coords * (WAVE_SCALE * 0.5) + windDir * timer * (windSpeed*0.2)-(col.xy/col.zz)*bend;
col += shSample(tex,nCoord + float2(+timer*0.03,+timer*0.02)).rgb*0.15;
nCoord = coords * (WAVE_SCALE* 0.8) + windDir * timer * (windSpeed*1.0)-(col.xy/col.zz)*bend;
col += shSample(tex, nCoord + float2(-timer*0.06,+timer*0.08)).rgb*0.15;
nCoord = coords * (WAVE_SCALE * 1.0) + windDir * timer * (windSpeed*1.3)-(col.xy/col.zz)*bend;
col += shSample(tex,nCoord + float2(+timer*0.08,-timer*0.06)).rgb*0.10;
return col;
}
float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 eyePosWS, float3 worldNormal, float3 lightDirectionWS0, float waterLevel, float waterTimer, float3 windDir_windSpeed)
{
float3 waterEyePos = intercept(worldPos.xyz, eyePosWS - worldPos, float3(0,1,0), waterLevel);
float waterDepth = shSaturate((waterEyePos.y - worldPos.y) / 50.0);
float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,1,0), waterLevel);
///\ todo clean this up
float causticdepth = length(causticPos-worldPos.xyz);
causticdepth = 1.0-shSaturate(causticdepth / VISIBILITY);
causticdepth = shSaturate(causticdepth);
// NOTE: the original shader calculated a tangent space basis here,
// but using only the world normal is cheaper and i couldn't see a visual difference
// also, if this effect gets moved to screen-space some day, it's unlikely to have tangent information
float3 causticNorm = worldNormal.xyz * perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).xzy * 2 - 1;
//float fresnel = pow(clamp(dot(LV,causticnorm),0.0,1.0),2.0);
float NdotL = max(dot(worldNormal.xyz, lightDirectionWS0.xyz),0.0);
float causticR = 1.0-perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
/// \todo sunFade
// float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*sunFade*causticdepth;
float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth;
float causticG = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
float causticB = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION*2.0, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
//caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*sunFade*causticdepth;
caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*causticdepth;
caustics *= 3;
// shore transition
caustics = shLerp (float3(1,1,1), caustics, waterDepth);
return caustics;
}

@ -11,9 +11,6 @@ material openmw_objects_base
scene_blend default
depth_write default
alpha_rejection default
shadow_transparency true // use diffuse alpha as mask for shadow
shadow_caster_material openmw_shadowcaster
pass
{

@ -94,7 +94,7 @@
// ----------------------------------- FRAGMENT ------------------------------------------
#if UNDERWATER
#include "caustics.h"
#include "underwater.h"
#endif
SH_BEGIN_PROGRAM
@ -163,7 +163,8 @@
shSampler2D(causticMap)
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
#endif
@ -262,22 +263,30 @@
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (worldPos.y > waterLevel)
float fogAmount = (cameraPos.y > 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 = clamp(pow(waterSunGradient*0.7+0.3,2.0),0.0,1.0);
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, vec3(0.0,-1.0,0.0));
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 waterSunColour = vec3(0.0,1.0,0.85)*waterSunGradient;
waterSunColour = (cameraPos.z < waterLevel) ? waterSunColour*0.5:waterSunColour*0.25;//below or above water?
float3 waterColour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
shOutputColour(0).xyz = waterColour;
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;
float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness;
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
#endif
#if MRT

@ -0,0 +1,22 @@
material quad
{
depth_write on
pass
{
vertex_program quad_vertex
fragment_program quad_fragment
depth_write $depth_write
texture_unit SceneBuffer
{
}
}
}
material quad_noDepthWrite
{
parent quad
depth_write off
}

@ -0,0 +1,25 @@
#include "core.h"
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shInput(float2, uv0)
shOutput(float2, UV)
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
UV = uv0;
}
#else
SH_BEGIN_PROGRAM
shInput(float2, UV)
shSampler2D(SceneBuffer)
SH_START_PROGRAM
{
shOutputColour(0) = shSample(SceneBuffer, UV);
}
#endif

@ -0,0 +1,15 @@
shader_set quad_vertex
{
source quad.shader
type vertex
profiles_cg vs_2_0 vp40 arbvp1
profiles_hlsl vs_2_0
}
shader_set quad_fragment
{
source quad.shader
type fragment
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
profiles_hlsl ps_2_0
}

@ -125,7 +125,7 @@
// ----------------------------------- FRAGMENT ------------------------------------------
#if UNDERWATER
#include "caustics.h"
#include "underwater.h"
#endif
SH_BEGIN_PROGRAM
@ -195,7 +195,8 @@
shSampler2D(causticMap)
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
#endif
@ -226,7 +227,7 @@
if (worldPos.y < waterLevel)
{
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
waterEyePos = intercept(worldPos, eyePosWS - worldPos, float3(0,1,0), waterLevel);
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,1,0), waterLevel);
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
}
@ -331,9 +332,44 @@
#if FOG
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
#if UNDERWATER
// regular fog only if fragment is above water
if (worldPos.y > waterLevel)
#endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
#endif
// prevent negative colour output (for example with negative lights)
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (cameraPos.y > 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.y <= waterLevel) ? watercolour : watercolour*0.3;
float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness;
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
#endif
#if MRT
shOutputColour(1) = float4(depth / far,1,1,1);

@ -14,6 +14,8 @@
#define ABBERATION 0.001 // chromatic abberation amount
#define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction
float3 intercept(float3 lineP,
float3 lineN,
float3 planeN,

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

@ -43,6 +43,8 @@
// tweakables ----------------------------------------------------
#define VISIBILITY 1500.0 // how far you can look through water
#define BIG_WAVES_X 0.3 // strength of big waves
#define BIG_WAVES_Y 0.3
@ -57,15 +59,15 @@
#define ABBERATION 0.001 // chromatic abberation amount
#define BUMP 1.5 // overall water surface bumpiness
#define REFL_BUMP 0.11 // reflection distortion amount
#define REFR_BUMP 0.08 // refraction distortion amount
#define REFL_BUMP 0.08 // reflection distortion amount
#define REFR_BUMP 0.06 // refraction distortion amount
#define SCATTER_AMOUNT 3.0 // amount of sunlight scattering
#define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering
#define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction
#define SPEC_HARDNESS 256 // specular highlights hardness
#define SPEC_HARDNESS 256 // specular highlights hardness
// ---------------------------------------------------------------
@ -201,16 +203,6 @@
// brighten up the refraction underwater
refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction;
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 = mix(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
// specular
float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS);
@ -221,8 +213,31 @@
shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, refraction, (1-shoreFade) * (1-isUnderwater));
// fog
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue);
if (isUnderwater == 1)
{
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 = mix(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
float darkness = VISIBILITY*2.0;
darkness = clamp((cameraPos.y+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);
}
}
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

@ -1,61 +0,0 @@
void main_vp
(
in float4 inPos : POSITION,
out float4 pos : POSITION,
out float2 uv0 : TEXCOORD0,
out float4 noiseCoord : TEXCOORD1,
uniform float4x4 worldViewProj,
uniform float timeVal,
uniform float scale
)
{
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
pos = mul(worldViewProj, inPos);
// The input positions adjusted by texel offsets, so clean up inaccuracies
inPos.xy = sign(inPos.xy);
// Convert to image-space
uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
noiseCoord = (pos + timeVal) * scale;
}
float4 main_fp_nomrt (float2 iTexCoord : TEXCOORD0,
float3 noiseCoord : TEXCOORD1,
uniform sampler2D RT : register(s0),
uniform sampler2D NormalMap : register(s1),
uniform sampler2D CausticMap : register(s2)) : COLOR
{
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
float4 col = tex2D(RT, iTexCoord + normal.xy * 0.015) +
(tex2D(CausticMap, noiseCoord) / 5);
col.xyz = lerp(col.xyz, float3(0.15, 0.40, 0.40), 0.4);
return col;
}
float4 main_fp (float2 iTexCoord : TEXCOORD0,
float3 noiseCoord : TEXCOORD1,
uniform float far,
uniform sampler2D RT : register(s0),
uniform sampler2D NormalMap : register(s1),
uniform sampler2D CausticMap : register(s2),
uniform sampler2D DepthMap : register(s3)) : COLOR
{
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
float depth = tex2D(DepthMap, iTexCoord + normal.xy * 0.015).r * far;
depth = saturate(depth / 2000.f);
float4 color = tex2D(RT, iTexCoord + normal.xy * 0.015) +
(tex2D(CausticMap, noiseCoord) / 5);
color.xyz = lerp(color.xyz, float3(0.15, 0.40, 0.40), 0.4);
return lerp(color, float4(0.15, 0.40, 0.40, 1), depth);
}

@ -1,121 +0,0 @@
void main_vp
(
in float4 iPos : POSITION
, in float2 iUv : TEXCOORD0
, out float4 oPos : POSITION
, out float3 oScreenCoords : TEXCOORD0
, out float2 oUv : TEXCOORD1
, out float oDepth : TEXCOORD2
, out float4 oEyeVector : TEXCOORD3
, uniform float4x4 wvpMat
, uniform float4 camPosObjSpace
)
{
oPos = mul(wvpMat, iPos);
oUv = iUv * 10; // uv scale
oDepth = oPos.z;
float4x4 scalemat = float4x4( 0.5, 0, 0, 0.5,
0, -0.5, 0, 0.5,
0, 0, 0.5, 0.5,
0, 0, 0, 1 );
float4 texcoordProj = mul(scalemat, oPos);
oScreenCoords = float3(texcoordProj.x, texcoordProj.y, texcoordProj.w);
oEyeVector = camPosObjSpace - iPos;
}
void main_fp
(
out float4 oColor : COLOR
, in float3 iScreenCoords : TEXCOORD0
, in float2 iUv : TEXCOORD1
, in float iDepth : TEXCOORD2
, in float4 iEyeVector : TEXCOORD3
, uniform float renderTargetFlipping
, uniform float4 lightPosObjSpace0
, uniform float4 lightSpecularColour0
, uniform sampler2D reflectionMap : register(s0)
, uniform sampler2D refractionMap : register(s1)
, uniform sampler2D depthMap : register(s2)
, uniform sampler2D normalMap : register(s3)
, uniform float time
, uniform float far
, uniform float4 fogParams
, uniform float4 fogColour
, uniform float isUnderwater
)
{
float2 screenCoords = iScreenCoords.xy / iScreenCoords.z;
screenCoords.y = (1-saturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y;
// No need for transparency since we are using a refraction map
oColor.a = 1;
// Sample screen-space depth map and subtract pixel depth to get the real water depth
float depthTex = tex2D(depthMap, screenCoords).r;
float depth1 = depthTex * far - iDepth;
depth1 = saturate(depth1 / 500.f);
// Simple wave effect. to be replaced by something better
float2 uv1 = iUv + time * float2(0.5, 0);
float2 uv2 = iUv + time * float2(0, 0.5);
float2 uv3 = iUv + time * float2(-0.5, 0);
float2 uv4 = iUv + time * float2(0, -0.5);
float4 normal = tex2D(normalMap, uv1) + tex2D(normalMap, uv2) + tex2D(normalMap, uv3) + tex2D(normalMap, uv4);
normal = normal / 4.f;
normal = 2*normal - 1;
float2 screenCoords_reflect = screenCoords + normal.yx * 0.05;
float2 screenCoords_refract = screenCoords + normal.yx * 0.05 * depth1;
// Sample depth again with the refracted coordinates
depthTex = tex2D(depthMap, screenCoords_refract).r;
float depth2 = (depthTex * far - iDepth) / 500.f;
depth2 = (depthTex == 0 ? 1 : depth2);
// if depth2 is less than 0, this means we would refract something which is above water,
// which we don't want to - so in that case, don't refract
if (depth2 < 0.25) // delta due to inaccuracies
{
screenCoords_refract = screenCoords;
depth2 = depth1;
}
depth2 = saturate(depth2);
float4 reflection = tex2D(reflectionMap, screenCoords_reflect);
float4 refraction = tex2D(refractionMap, screenCoords_refract);
// tangent to object space
normal.xyz = normal.xzy;
iEyeVector.xyz = normalize(iEyeVector.xyz);
// fresnel
float facing = 1.0 - max(abs(dot(iEyeVector.xyz, normal.xyz)), 0);
float reflectionFactor = saturate(0.35 + 0.65 * pow(facing, 2));
// specular
float3 lightDir = normalize(lightPosObjSpace0.xyz); // assumes that light 0 is a directional light
float3 halfVector = normalize(iEyeVector + lightDir);
float specular = pow(max(dot(normal.xyz, halfVector.xyz), 0), 64);
float opacity = depth2 * saturate(reflectionFactor + specular);
opacity *= (1-isUnderwater);
reflection.xyz += lightSpecularColour0.xyz * specular;
oColor.xyz = lerp(refraction.xyz, reflection.xyz, opacity);
oColor.xyz = lerp(oColor.xyz, float3(0.15, 0.40, 0.40), isUnderwater*0.6); // underwater tint color
oColor.xyz = lerp(oColor.xyz, float3(0.15, 0.40, 0.40), saturate(isUnderwater * (iDepth / 2000.f))); // underwater fog
// add fog
//float fogValue = saturate((iDepth - fogParams.y) * fogParams.w);
//oColor.xyz = lerp(oColor.xyz, fogColour, fogValue);
}

@ -1,45 +0,0 @@
compositor UnderwaterNoMRT
{
technique
{
texture rt0 target_width target_height PF_R8G8B8
target rt0 { input previous }
target_output
{
// Start with clear output
input none
pass render_quad
{
material Water/CompositorNoMRT
input 0 rt0
}
}
}
}
compositor Underwater
{
technique
{
texture_ref scene gbuffer mrt_output
texture rt0 target_width target_height PF_R8G8B8
target rt0 { input previous }
target_output
{
// Start with clear output
input none
pass render_quad
{
material Water/Compositor
input 0 rt0
}
}
}
}
Loading…
Cancel
Save