When a custom near clip plane is used, we need to fix up a second viewproj matrix manually to get proper depth values in the vertex shader. This fixes fog on reflections.

actorid
scrawl 12 years ago
parent 32b837ebd4
commit 6cceb04adf

@ -8,6 +8,8 @@
#include <OgreViewport.h>
#include <OgreRoot.h>
#include <extern/shiny/Main/Factory.hpp>
#include "renderconst.hpp"
namespace MWRender
@ -30,7 +32,7 @@ namespace MWRender
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky);
vp->setMaterialScheme("water_reflection");
vp->setMaterialScheme("water_refraction");
vp->setBackgroundColour (Ogre::ColourValue(0.0078, 0.0576, 0.150));
mRenderTarget->setAutoUpdated(true);
mRenderTarget->addListener(this);
@ -54,6 +56,12 @@ namespace MWRender
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
mCamera->setFOVy(mParentCamera->getFOVy());
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
// since all we are interested in is depth, we only need the third row of the matrix.
Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix ();
sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]);
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (row3));
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
@ -62,6 +70,7 @@ namespace MWRender
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mCamera->disableCustomNearClipPlane ();
mRenderActive = false;
}

@ -140,6 +140,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false");
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (new sh::Vector4(0,0,0,0)));
applyCompositors();

@ -144,6 +144,12 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
mSky->setSkyPosition(pos);
mCamera->enableReflection(mWaterPlane);
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
// since all we are interested in is depth, we only need the third row of the matrix.
Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix ();
sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]);
sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty<sh::Vector4> (row3));
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
}

@ -23,12 +23,21 @@
#define VERTEX_LIGHTING 1
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
#ifdef SH_VERTEX_SHADER
// ------------------------------------- VERTEX ---------------------------------------
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
#if VIEWPROJ_FIX
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
shUniform(float4, vpRow2Fix) @shSharedParameter(vpRow2Fix, vpRow2Fix)
shUniform(float4x4, vpMatrix) @shAutoConstant(vpMatrix, viewproj_matrix)
#endif
shVertexInput(float2, uv0)
shOutput(float2, UV)
shNormalInput(float4)
@ -65,7 +74,6 @@
#if SHADOWS
shOutput(float4, lightSpacePos0)
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
#endif
#if SHADOWS_PSSM
@ -73,7 +81,9 @@
shOutput(float4, lightSpacePos@shIterator)
shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator)
@shEndForeach
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
#if !VIEWPROJ_FIX
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
#endif
#endif
#if VERTEX_LIGHTING
@ -89,9 +99,28 @@
#endif
#ifdef NEED_DEPTH
#if VIEWPROJ_FIX
float4x4 vpFixed = vpMatrix;
#if !SH_GLSL
vpFixed[2] = vpRow2Fix;
#else
vpFixed[0][2] = vpRow2Fix.x;
vpFixed[1][2] = vpRow2Fix.y;
vpFixed[2][2] = vpRow2Fix.z;
vpFixed[3][2] = vpRow2Fix.w;
#endif
float4x4 fixedWVP = shMatrixMult(vpFixed, worldMatrix);
depthPassthrough = shMatrixMult(fixedWVP, shInputPosition).z;
#else
depthPassthrough = shOutputPosition.z;
#endif
#endif
#if LIGHTING
objSpacePositionPassthrough = shInputPosition.xyz;
#endif

@ -1,8 +1,13 @@
configuration water_reflection
{
fog false
shadows false
shadows_pssm false
viewproj_fix true
}
configuration water_refraction
{
viewproj_fix true
}
configuration local_map

@ -23,6 +23,8 @@
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
#if NEED_DEPTH
@shAllocatePassthrough(1, depth)
@ -51,6 +53,10 @@
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
shUniform(float4x4, viewProjMatrix) @shAutoConstant(viewProjMatrix, viewproj_matrix)
#if VIEWPROJ_FIX
shUniform(float4, vpRow2Fix) @shSharedParameter(vpRow2Fix, vpRow2Fix)
#endif
shUniform(float2, lodMorph) @shAutoConstant(lodMorph, custom, 1001)
shVertexInput(float2, uv0)
@ -94,7 +100,25 @@
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
#if NEED_DEPTH
#if VIEWPROJ_FIX
float4x4 vpFixed = viewProjMatrix;
#if !SH_GLSL
vpFixed[2] = vpRow2Fix;
#else
vpFixed[0][2] = vpRow2Fix.x;
vpFixed[1][2] = vpRow2Fix.y;
vpFixed[2][2] = vpRow2Fix.z;
vpFixed[3][2] = vpRow2Fix.w;
#endif
float4x4 fixedWVP = shMatrixMult(vpFixed, worldMatrix);
float depth = shMatrixMult(fixedWVP, shInputPosition).z;
@shPassthroughAssign(depth, depth);
#else
@shPassthroughAssign(depth, shOutputPosition.z);
#endif
#endif
@shPassthroughAssign(UV, uv0);

Loading…
Cancel
Save