1
0
Fork 1
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:
Mads Buvik Sandvei 2020-12-08 21:37:27 +01:00
parent 5beb0bc799
commit 1bebe51c29
3 changed files with 96 additions and 59 deletions

View file

@ -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)

View file

@ -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 };

View file

@ -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