mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 10:45:33 +00:00
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.
This commit is contained in:
parent
32b837ebd4
commit
6cceb04adf
6 changed files with 79 additions and 4 deletions
|
@ -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…
Reference in a new issue