mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
Z-up conversion: water, sky
This commit is contained in:
parent
3cb3ec91c0
commit
3ef952172d
7 changed files with 43 additions and 43 deletions
|
@ -365,7 +365,7 @@ void RenderingManager::update (float duration, bool paused)
|
|||
float *fpos = data.getPosition().pos;
|
||||
|
||||
// only for LocalMap::updatePlayer()
|
||||
Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]);
|
||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
||||
|
||||
Ogre::SceneNode *node = data.getBaseNode();
|
||||
Ogre::Quaternion orient =
|
||||
|
@ -381,7 +381,7 @@ void RenderingManager::update (float duration, bool paused)
|
|||
mWater->updateUnderwater(
|
||||
world->isUnderwater(
|
||||
world->getPlayer().getPlayer().getCell(),
|
||||
Ogre::Vector3(cam.x, -cam.z, cam.y))
|
||||
cam)
|
||||
);
|
||||
mWater->update(duration);
|
||||
}
|
||||
|
@ -613,8 +613,7 @@ void RenderingManager::sunDisable()
|
|||
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
|
||||
{
|
||||
// direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
|
||||
// then convert from MW to ogre coordinates (swap y,z and make y negative)
|
||||
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y));
|
||||
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.y, -direction.z));
|
||||
|
||||
mSkyManager->setSunDirection(direction);
|
||||
}
|
||||
|
|
|
@ -236,7 +236,6 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
|||
{
|
||||
mSceneMgr = pMwRoot->getCreator();
|
||||
mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
|
||||
mRootNode->setInheritOrientation(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,9 +42,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
|||
|
||||
mIsUnderwater = false;
|
||||
|
||||
mWaterPlane = Plane(Vector3::UNIT_Y, 0);
|
||||
mWaterPlane = Plane(Vector3::UNIT_Z, 0);
|
||||
|
||||
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z);
|
||||
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);
|
||||
|
||||
mWater = mSceneManager->createEntity("water");
|
||||
mWater->setVisibilityFlags(RV_Water);
|
||||
|
@ -168,12 +168,12 @@ void Water::setHeight(const float height)
|
|||
{
|
||||
mTop = height;
|
||||
|
||||
mWaterPlane = Plane(Vector3::UNIT_Y, height);
|
||||
mWaterPlane = Plane(Vector3::UNIT_Z, height);
|
||||
|
||||
// small error due to reflection texture size & reflection distortion
|
||||
mErrorPlane = Plane(Vector3::UNIT_Y, height - 5);
|
||||
mErrorPlane = Plane(Vector3::UNIT_Z, height - 5);
|
||||
|
||||
mWaterNode->setPosition(0, height, 0);
|
||||
mWaterNode->setPosition(0, 0, height);
|
||||
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ Water::updateUnderwater(bool underwater)
|
|||
|
||||
Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
|
||||
{
|
||||
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2));
|
||||
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop);
|
||||
}
|
||||
|
||||
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
|
||||
|
@ -216,7 +216,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
|
|||
mReflectionRenderActive = true;
|
||||
|
||||
Vector3 pos = mCamera->getRealPosition();
|
||||
pos.y = mTop*2 - pos.y;
|
||||
pos.z = mTop*2 - pos.z;
|
||||
mSky->setSkyPosition(pos);
|
||||
mReflectionCamera->enableReflection(mWaterPlane);
|
||||
}
|
||||
|
|
|
@ -225,9 +225,9 @@
|
|||
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,1,0), waterLevel);
|
||||
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.y >= waterLevel || waterEnabled != 1.f)
|
||||
if (worldPos.z >= waterLevel || waterEnabled != 1.f)
|
||||
caustics = float3(1,1,1);
|
||||
#endif
|
||||
|
||||
|
@ -269,7 +269,7 @@
|
|||
|
||||
#if UNDERWATER
|
||||
// regular fog only if fragment is above water
|
||||
if (worldPos.y > waterLevel || waterEnabled != 1.f)
|
||||
if (worldPos.z > waterLevel || waterEnabled != 1.f)
|
||||
#endif
|
||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
|
||||
#endif
|
||||
|
@ -278,7 +278,7 @@
|
|||
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
|
||||
|
||||
#if UNDERWATER
|
||||
float fogAmount = (cameraPos.y > waterLevel)
|
||||
float fogAmount = (cameraPos.z > waterLevel)
|
||||
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
|
||||
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
|
||||
|
||||
|
@ -292,14 +292,14 @@
|
|||
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;
|
||||
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;
|
||||
watercolour = (cameraPos.z <= 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;
|
||||
float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
|
||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@
|
|||
float toMorph = -min(0, sign(uv1.y - lodMorph.y));
|
||||
|
||||
// morph
|
||||
// this assumes XZ terrain alignment
|
||||
worldPos.y += uv1.x * toMorph * lodMorph.x;
|
||||
// this assumes XY terrain alignment
|
||||
worldPos.z += uv1.x * toMorph * lodMorph.x;
|
||||
|
||||
|
||||
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
|
||||
|
@ -233,9 +233,9 @@
|
|||
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,1,0), waterLevel);
|
||||
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.y >= waterLevel)
|
||||
if (worldPos.z >= waterLevel)
|
||||
caustics = float3(1,1,1);
|
||||
|
||||
|
||||
|
@ -341,7 +341,7 @@
|
|||
|
||||
#if UNDERWATER
|
||||
// regular fog only if fragment is above water
|
||||
if (worldPos.y > waterLevel)
|
||||
if (worldPos.z > waterLevel)
|
||||
#endif
|
||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
|
||||
#endif
|
||||
|
@ -350,7 +350,7 @@
|
|||
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
|
||||
|
||||
#if UNDERWATER
|
||||
float fogAmount = (cameraPos.y > waterLevel)
|
||||
float fogAmount = (cameraPos.z > waterLevel)
|
||||
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
|
||||
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
|
||||
|
||||
|
@ -365,14 +365,14 @@
|
|||
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
|
||||
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;
|
||||
watercolour = (cameraPos.z <= 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;
|
||||
float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
|
||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -79,9 +79,9 @@ float3 perturb(shTexture2D tex, float2 coords, float bend, float2 windDir, float
|
|||
|
||||
float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos, float3 worldNormal, float3 lightDirectionWS0, float waterLevel, float waterTimer, float3 windDir_windSpeed)
|
||||
{
|
||||
float waterDepth = shSaturate((waterEyePos.y - worldPos.y) / 50.0);
|
||||
float waterDepth = shSaturate((waterEyePos.y - worldPos.z) / 50.0);
|
||||
|
||||
float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,1,0), waterLevel);
|
||||
float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,0,1), waterLevel);
|
||||
|
||||
///\ todo clean this up
|
||||
float causticdepth = length(causticPos-worldPos.xyz);
|
||||
|
@ -91,7 +91,7 @@ float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos,
|
|||
// 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;
|
||||
float3 causticNorm = worldNormal.xyz * perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).xyz * 2 - 1;
|
||||
|
||||
//float fresnel = pow(clamp(dot(LV,causticnorm),0.0,1.0),2.0);
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
#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_AMOUNT 1.0 // amount of sunlight scattering
|
||||
#define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering
|
||||
|
||||
#define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction
|
||||
|
@ -219,25 +219,27 @@
|
|||
|
||||
float3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +
|
||||
normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y +
|
||||
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xzy;
|
||||
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xyz;
|
||||
|
||||
normal = normalize(float3(normal.x * BUMP, normal.y, normal.z * BUMP));
|
||||
normal = normalize(float3(normal.x * BUMP, normal.y * BUMP, normal.z));
|
||||
normal = float3(normal.x, normal.y, -normal.z);
|
||||
|
||||
// normal for sunlight scattering
|
||||
float3 lNormal = (normal0 * BIG_WAVES_X*0.5 + normal1 * BIG_WAVES_Y*0.5 +
|
||||
normal2 * MID_WAVES_X*0.2 + normal3 * MID_WAVES_Y*0.2 +
|
||||
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xzy;
|
||||
lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y, lNormal.z * BUMP));
|
||||
|
||||
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xyz;
|
||||
lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y * BUMP, lNormal.z));
|
||||
lNormal = float3(lNormal.x, lNormal.y, -lNormal.z);
|
||||
|
||||
|
||||
float3 lVec = normalize(sunPosition.xyz);
|
||||
float3 vVec = normalize(position.xyz - cameraPos.xyz);
|
||||
|
||||
|
||||
float isUnderwater = (cameraPos.y > 0) ? 0.0 : 1.0;
|
||||
float isUnderwater = (cameraPos.z > 0) ? 0.0 : 1.0;
|
||||
|
||||
// sunlight scattering
|
||||
float3 pNormal = float3(0,1,0);
|
||||
float3 pNormal = float3(0,0,1);
|
||||
float3 lR = reflect(lVec, lNormal);
|
||||
float3 llR = reflect(lVec, pNormal);
|
||||
|
||||
|
@ -246,13 +248,13 @@
|
|||
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)));
|
||||
|
||||
// fresnel
|
||||
float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air
|
||||
float ior = (cameraPos.z>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air
|
||||
float fresnel = fresnel_dielectric(-vVec, normal, ior);
|
||||
|
||||
fresnel = shSaturate(fresnel);
|
||||
|
||||
// reflection
|
||||
float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb);
|
||||
float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xy*REFL_BUMP)).rgb);
|
||||
|
||||
// refraction
|
||||
float3 R = reflect(vVec, normal);
|
||||
|
@ -260,13 +262,13 @@
|
|||
// check the depth at the refracted coords, and don't do any normal distortion for the refraction if the object to refract
|
||||
// is actually above the water (objectDepth < waterDepth)
|
||||
// this solves silhouettes around objects above the water
|
||||
float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xz*REFR_BUMP)).x * far - depthPassthrough;
|
||||
float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xy*REFR_BUMP)).x * far - depthPassthrough;
|
||||
float doRefraction = (refractDepth < 0) ? 0.f : 1.f;
|
||||
|
||||
float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP * doRefraction))*1.0).rgb);
|
||||
float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xy*REFR_BUMP * doRefraction))*1.0).rgb);
|
||||
|
||||
// brighten up the refraction underwater
|
||||
refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction;
|
||||
refraction = (cameraPos.z < 0) ? shSaturate(refraction * 1.5) : refraction;
|
||||
|
||||
// specular
|
||||
float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS);
|
||||
|
@ -290,7 +292,7 @@
|
|||
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.y+darkness)/darkness,0.2,1.0);
|
||||
darkness = clamp((cameraPos.z+darkness)/darkness,0.2,1.0);
|
||||
|
||||
|
||||
float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY);
|
||||
|
|
Loading…
Reference in a new issue