mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-10-05 02:26: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)
|
||||
, mGeometryShaderMask(geometryShaderMask)
|
||||
, mNoShaderMask(noShaderMask)
|
||||
, mMasterConfig(new SharedShadowMapConfig)
|
||||
, mSlaveConfig(new SharedShadowMapConfig)
|
||||
, mSharedShadowMaps(Settings::Manager::getBool("shared shadow maps", "Stereo"))
|
||||
{
|
||||
if (technique == Technique::None)
|
||||
// Do nothing
|
||||
return;
|
||||
|
||||
mMasterConfig->_id = "STEREO";
|
||||
mMasterConfig->_master = true;
|
||||
mSlaveConfig->_id = "STEREO";
|
||||
mSlaveConfig->_master = false;
|
||||
|
||||
SceneUtil::FindByNameVisitor findScene("Scene Root");
|
||||
mRoot->accept(findScene);
|
||||
mScene = findScene.mFoundNode;
|
||||
|
@ -292,6 +300,12 @@ namespace Misc
|
|||
mRightCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
mRightCamera->setCullMask(mMainCamera->getCullMask());
|
||||
|
||||
if (mSharedShadowMaps)
|
||||
{
|
||||
mLeftCamera->setUserData(mMasterConfig);
|
||||
mRightCamera->setUserData(mSlaveConfig);
|
||||
}
|
||||
|
||||
// Slave cameras must have their viewports defined immediately
|
||||
auto width = mMainCamera->getViewport()->width();
|
||||
auto height = mMainCamera->getViewport()->height();
|
||||
|
@ -366,8 +380,6 @@ namespace Misc
|
|||
auto width = mMainCamera->getViewport()->width();
|
||||
auto height = mMainCamera->getViewport()->height();
|
||||
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
// 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.
|
||||
// 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.";
|
||||
mMainCamera->setCullingActive(false);
|
||||
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
|
||||
|
@ -426,6 +438,9 @@ namespace Misc
|
|||
auto frustumViewMatrix = viewMatrix * frustumView.pose.viewMatrix(true);
|
||||
auto frustumProjectionMatrix = frustumView.fov.perspectiveMatrix(near + nearFarOffset, far + nearFarOffset);
|
||||
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
|
||||
// Update camera with frustum matrices
|
||||
mMainCamera->setViewMatrix(frustumViewMatrix);
|
||||
mMainCamera->setProjectionMatrix(frustumProjectionMatrix);
|
||||
|
@ -439,6 +454,18 @@ namespace Misc
|
|||
|
||||
mLeftCamera->setViewport(0, 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());
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <components/sceneutil/mwshadowtechnique.hpp>
|
||||
|
||||
// Some cursed headers like to define these
|
||||
#if defined(near) || defined(far)
|
||||
#undef near
|
||||
|
@ -122,6 +124,11 @@ namespace Misc
|
|||
osg::ref_ptr<osg::Camera> mLeftCamera{ 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
|
||||
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.
|
||||
# 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
|
||||
|
||||
# May accelerate the BruteForce method when shadows are enabled
|
||||
shared shadow maps = true
|
Loading…
Reference in a new issue