mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-29 19:36:43 +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 <OgreViewport.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include "renderconst.hpp"
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -30,7 +32,7 @@ namespace MWRender
|
||||||
vp->setOverlaysEnabled(false);
|
vp->setOverlaysEnabled(false);
|
||||||
vp->setShadowsEnabled(false);
|
vp->setShadowsEnabled(false);
|
||||||
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky);
|
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));
|
vp->setBackgroundColour (Ogre::ColourValue(0.0078, 0.0576, 0.150));
|
||||||
mRenderTarget->setAutoUpdated(true);
|
mRenderTarget->setAutoUpdated(true);
|
||||||
mRenderTarget->addListener(this);
|
mRenderTarget->addListener(this);
|
||||||
|
@ -54,6 +56,12 @@ namespace MWRender
|
||||||
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
|
mCamera->setAspectRatio(mParentCamera->getAspectRatio());
|
||||||
mCamera->setFOVy(mParentCamera->getFOVy());
|
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
|
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
|
||||||
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
|
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane);
|
||||||
|
|
||||||
|
@ -62,6 +70,7 @@ namespace MWRender
|
||||||
|
|
||||||
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
||||||
{
|
{
|
||||||
|
mCamera->disableCustomNearClipPlane ();
|
||||||
mRenderActive = false;
|
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 ("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 ().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 ("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();
|
applyCompositors();
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,12 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
|
||||||
mSky->setSkyPosition(pos);
|
mSky->setSkyPosition(pos);
|
||||||
mCamera->enableReflection(mWaterPlane);
|
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
|
// enable clip plane here to take advantage of CPU culling for overwater or underwater objects
|
||||||
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
|
mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,21 @@
|
||||||
|
|
||||||
#define VERTEX_LIGHTING 1
|
#define VERTEX_LIGHTING 1
|
||||||
|
|
||||||
|
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
|
||||||
|
|
||||||
#ifdef SH_VERTEX_SHADER
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
// ------------------------------------- VERTEX ---------------------------------------
|
// ------------------------------------- VERTEX ---------------------------------------
|
||||||
|
|
||||||
SH_BEGIN_PROGRAM
|
SH_BEGIN_PROGRAM
|
||||||
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
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)
|
shVertexInput(float2, uv0)
|
||||||
shOutput(float2, UV)
|
shOutput(float2, UV)
|
||||||
shNormalInput(float4)
|
shNormalInput(float4)
|
||||||
|
@ -65,7 +74,6 @@
|
||||||
#if SHADOWS
|
#if SHADOWS
|
||||||
shOutput(float4, lightSpacePos0)
|
shOutput(float4, lightSpacePos0)
|
||||||
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
|
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
|
||||||
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHADOWS_PSSM
|
#if SHADOWS_PSSM
|
||||||
|
@ -73,8 +81,10 @@
|
||||||
shOutput(float4, lightSpacePos@shIterator)
|
shOutput(float4, lightSpacePos@shIterator)
|
||||||
shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator)
|
shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator)
|
||||||
@shEndForeach
|
@shEndForeach
|
||||||
|
#if !VIEWPROJ_FIX
|
||||||
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if VERTEX_LIGHTING
|
#if VERTEX_LIGHTING
|
||||||
shOutput(float3, lightResult)
|
shOutput(float3, lightResult)
|
||||||
|
@ -89,9 +99,28 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NEED_DEPTH
|
#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;
|
depthPassthrough = shOutputPosition.z;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LIGHTING
|
#if LIGHTING
|
||||||
objSpacePositionPassthrough = shInputPosition.xyz;
|
objSpacePositionPassthrough = shInputPosition.xyz;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
configuration water_reflection
|
configuration water_reflection
|
||||||
{
|
{
|
||||||
fog false
|
|
||||||
shadows false
|
shadows false
|
||||||
shadows_pssm false
|
shadows_pssm false
|
||||||
|
viewproj_fix true
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration water_refraction
|
||||||
|
{
|
||||||
|
viewproj_fix true
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration local_map
|
configuration local_map
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING
|
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING
|
||||||
|
|
||||||
|
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
|
||||||
|
|
||||||
|
|
||||||
#if NEED_DEPTH
|
#if NEED_DEPTH
|
||||||
@shAllocatePassthrough(1, depth)
|
@shAllocatePassthrough(1, depth)
|
||||||
|
@ -51,6 +53,10 @@
|
||||||
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
shUniform(float4x4, viewProjMatrix) @shAutoConstant(viewProjMatrix, viewproj_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)
|
shUniform(float2, lodMorph) @shAutoConstant(lodMorph, custom, 1001)
|
||||||
|
|
||||||
shVertexInput(float2, uv0)
|
shVertexInput(float2, uv0)
|
||||||
|
@ -94,7 +100,25 @@
|
||||||
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
|
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
|
||||||
|
|
||||||
#if NEED_DEPTH
|
#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);
|
@shPassthroughAssign(depth, shOutputPosition.z);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@shPassthroughAssign(UV, uv0);
|
@shPassthroughAssign(UV, uv0);
|
||||||
|
|
Loading…
Reference in a new issue