mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-10-04 23:56:30 +00:00
Make use of shared shadow maps in the brute force method
This commit is contained in:
parent
5beb0bc799
commit
1bebe51c29
3 changed files with 96 additions and 59 deletions
|
@ -233,11 +233,19 @@ namespace Misc
|
||||||
, mTechnique(technique)
|
, mTechnique(technique)
|
||||||
, mGeometryShaderMask(geometryShaderMask)
|
, mGeometryShaderMask(geometryShaderMask)
|
||||||
, mNoShaderMask(noShaderMask)
|
, mNoShaderMask(noShaderMask)
|
||||||
|
, mMasterConfig(new SharedShadowMapConfig)
|
||||||
|
, mSlaveConfig(new SharedShadowMapConfig)
|
||||||
|
, mSharedShadowMaps(Settings::Manager::getBool("shared shadow maps", "Stereo"))
|
||||||
{
|
{
|
||||||
if (technique == Technique::None)
|
if (technique == Technique::None)
|
||||||
// Do nothing
|
// Do nothing
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mMasterConfig->_id = "STEREO";
|
||||||
|
mMasterConfig->_master = true;
|
||||||
|
mSlaveConfig->_id = "STEREO";
|
||||||
|
mSlaveConfig->_master = false;
|
||||||
|
|
||||||
SceneUtil::FindByNameVisitor findScene("Scene Root");
|
SceneUtil::FindByNameVisitor findScene("Scene Root");
|
||||||
mRoot->accept(findScene);
|
mRoot->accept(findScene);
|
||||||
mScene = findScene.mFoundNode;
|
mScene = findScene.mFoundNode;
|
||||||
|
@ -292,6 +300,12 @@ namespace Misc
|
||||||
mRightCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
mRightCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
mRightCamera->setCullMask(mMainCamera->getCullMask());
|
mRightCamera->setCullMask(mMainCamera->getCullMask());
|
||||||
|
|
||||||
|
if (mSharedShadowMaps)
|
||||||
|
{
|
||||||
|
mLeftCamera->setUserData(mMasterConfig);
|
||||||
|
mRightCamera->setUserData(mSlaveConfig);
|
||||||
|
}
|
||||||
|
|
||||||
// Slave cameras must have their viewports defined immediately
|
// Slave cameras must have their viewports defined immediately
|
||||||
auto width = mMainCamera->getViewport()->width();
|
auto width = mMainCamera->getViewport()->width();
|
||||||
auto height = mMainCamera->getViewport()->height();
|
auto height = mMainCamera->getViewport()->height();
|
||||||
|
@ -366,8 +380,6 @@ namespace Misc
|
||||||
auto width = mMainCamera->getViewport()->width();
|
auto width = mMainCamera->getViewport()->width();
|
||||||
auto height = mMainCamera->getViewport()->height();
|
auto height = mMainCamera->getViewport()->height();
|
||||||
|
|
||||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
|
||||||
{
|
|
||||||
// To correctly cull when drawing stereo using the geometry shader, the main camera must
|
// To correctly cull when drawing stereo using the geometry shader, the main camera must
|
||||||
// draw a fake view+perspective that includes the full frustums of both the left and right eyes.
|
// draw a fake view+perspective that includes the full frustums of both the left and right eyes.
|
||||||
// This frustum will be computed as a perspective frustum from a position P slightly behind the eyes L and R
|
// This frustum will be computed as a perspective frustum from a position P slightly behind the eyes L and R
|
||||||
|
@ -403,7 +415,7 @@ namespace Misc
|
||||||
Log(Debug::Error) << "Total FOV exceeds 180 degrees. Case cannot be culled in single-pass VR. Disabling culling to cope. Consider switching to dual-pass VR.";
|
Log(Debug::Error) << "Total FOV exceeds 180 degrees. Case cannot be culled in single-pass VR. Disabling culling to cope. Consider switching to dual-pass VR.";
|
||||||
mMainCamera->setCullingActive(false);
|
mMainCamera->setCullingActive(false);
|
||||||
return;
|
return;
|
||||||
// TODO: An explicit frustum projection could cope, so implement that later. Guarantee you there will be VR headsets with total fov > 180 in the future. Maybe already.
|
// TODO: An explicit frustum projection could cope, so implement that later. Guarantee you there will be VR headsets with total horizontal fov > 180 in the future. Maybe already.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the law of sines on the triangle spanning PLR to determine P
|
// Use the law of sines on the triangle spanning PLR to determine P
|
||||||
|
@ -426,6 +438,9 @@ namespace Misc
|
||||||
auto frustumViewMatrix = viewMatrix * frustumView.pose.viewMatrix(true);
|
auto frustumViewMatrix = viewMatrix * frustumView.pose.viewMatrix(true);
|
||||||
auto frustumProjectionMatrix = frustumView.fov.perspectiveMatrix(near + nearFarOffset, far + nearFarOffset);
|
auto frustumProjectionMatrix = frustumView.fov.perspectiveMatrix(near + nearFarOffset, far + nearFarOffset);
|
||||||
|
|
||||||
|
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||||
|
{
|
||||||
|
|
||||||
// Update camera with frustum matrices
|
// Update camera with frustum matrices
|
||||||
mMainCamera->setViewMatrix(frustumViewMatrix);
|
mMainCamera->setViewMatrix(frustumViewMatrix);
|
||||||
mMainCamera->setProjectionMatrix(frustumProjectionMatrix);
|
mMainCamera->setProjectionMatrix(frustumProjectionMatrix);
|
||||||
|
@ -439,6 +454,18 @@ namespace Misc
|
||||||
|
|
||||||
mLeftCamera->setViewport(0, 0, width / 2, height);
|
mLeftCamera->setViewport(0, 0, width / 2, height);
|
||||||
mRightCamera->setViewport(width / 2, 0, width / 2, height);
|
mRightCamera->setViewport(width / 2, 0, width / 2, height);
|
||||||
|
|
||||||
|
if (mMasterConfig->_projection == nullptr)
|
||||||
|
mMasterConfig->_projection = new osg::RefMatrix;
|
||||||
|
if (mMasterConfig->_modelView == nullptr)
|
||||||
|
mMasterConfig->_modelView = new osg::RefMatrix;
|
||||||
|
|
||||||
|
if (mSharedShadowMaps)
|
||||||
|
{
|
||||||
|
mMasterConfig->_referenceFrame = mMainCamera->getReferenceFrame();
|
||||||
|
mMasterConfig->_modelView->set(frustumViewMatrix);
|
||||||
|
mMasterConfig->_projection->set(projectionMatrix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,9 +489,9 @@ namespace Misc
|
||||||
stereoViewProjectionsUniform->setElement(1, frustumViewMatrixInverse * mRightCamera->getViewMatrix() * mRightCamera->getProjectionMatrix());
|
stereoViewProjectionsUniform->setElement(1, frustumViewMatrixInverse * mRightCamera->getViewMatrix() * mRightCamera->getProjectionMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StereoView::setUpdateViewCallback(std::shared_ptr<UpdateViewCallback> cb)
|
void StereoView::setUpdateViewCallback(std::shared_ptr<UpdateViewCallback> cb_)
|
||||||
{
|
{
|
||||||
this->cb = cb;
|
cb = cb_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableStereoForCamera(osg::Camera* camera)
|
void disableStereoForCamera(osg::Camera* camera)
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <components/sceneutil/mwshadowtechnique.hpp>
|
||||||
|
|
||||||
// Some cursed headers like to define these
|
// Some cursed headers like to define these
|
||||||
#if defined(near) || defined(far)
|
#if defined(near) || defined(far)
|
||||||
#undef near
|
#undef near
|
||||||
|
@ -122,6 +124,11 @@ namespace Misc
|
||||||
osg::ref_ptr<osg::Camera> mLeftCamera{ new osg::Camera };
|
osg::ref_ptr<osg::Camera> mLeftCamera{ new osg::Camera };
|
||||||
osg::ref_ptr<osg::Camera> mRightCamera{ new osg::Camera };
|
osg::ref_ptr<osg::Camera> mRightCamera{ new osg::Camera };
|
||||||
|
|
||||||
|
using SharedShadowMapConfig = SceneUtil::MWShadowTechnique::SharedShadowMapConfig;
|
||||||
|
osg::ref_ptr<SharedShadowMapConfig> mMasterConfig;
|
||||||
|
osg::ref_ptr<SharedShadowMapConfig> mSlaveConfig;
|
||||||
|
bool mSharedShadowMaps;
|
||||||
|
|
||||||
// Camera viewports
|
// Camera viewports
|
||||||
bool flipViewOrder{ true };
|
bool flipViewOrder{ true };
|
||||||
|
|
||||||
|
|
|
@ -964,3 +964,6 @@ stereo enabled = false
|
||||||
# BruteForce: Generates stereo using two cameras and two cull/render passes. Choose this if your game is GPU-bound.
|
# BruteForce: Generates stereo using two cameras and two cull/render passes. Choose this if your game is GPU-bound.
|
||||||
# GeometryShader: Generates stereo in a single pass using automatically generated geometry shaders. May break custom shaders. Choose this if your game is CPU-bound.
|
# GeometryShader: Generates stereo in a single pass using automatically generated geometry shaders. May break custom shaders. Choose this if your game is CPU-bound.
|
||||||
stereo method = GeometryShader
|
stereo method = GeometryShader
|
||||||
|
|
||||||
|
# May accelerate the BruteForce method when shadows are enabled
|
||||||
|
shared shadow maps = true
|
Loading…
Reference in a new issue