1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-27 18:11:34 +00:00

Change assosiative order of stereo-related matrix multiplications to reduce FP errors.

This commit is contained in:
Mads Buvik Sandvei 2023-03-11 14:00:39 +01:00
parent 93a72a6368
commit 00e02bb326
4 changed files with 13 additions and 21 deletions

View file

@ -47,7 +47,7 @@ namespace MWRender
auto& sm = Stereo::Manager::instance(); auto& sm = Stereo::Manager::instance();
auto view = sm.getEye(cv); auto view = sm.getEye(cv);
int index = view == Stereo::Eye::Right ? 1 : 0; int index = view == Stereo::Eye::Right ? 1 : 0;
auto projectionMatrix = sm.computeEyeViewOffset(index) * sm.computeEyeProjection(index, true); auto projectionMatrix = sm.computeEyeProjection(index, true);
postProcessor->getStateUpdater()->setProjectionMatrix(projectionMatrix); postProcessor->getStateUpdater()->setProjectionMatrix(projectionMatrix);
} }

View file

@ -118,14 +118,14 @@ namespace MWRender
{ {
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix) if (uProjectionMatrix)
uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(0) * Stereo::Manager::instance().computeEyeProjection(0, SceneUtil::AutoDepth::isReversed())); uProjectionMatrix->set(Stereo::Manager::instance().computeEyeProjection(0, SceneUtil::AutoDepth::isReversed()));
} }
void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override
{ {
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix) if (uProjectionMatrix)
uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(1) * Stereo::Manager::instance().computeEyeProjection(1, SceneUtil::AutoDepth::isReversed())); uProjectionMatrix->set(Stereo::Manager::instance().computeEyeProjection(1, SceneUtil::AutoDepth::isReversed()));
} }
void setProjectionMatrix(const osg::Matrixf& projectionMatrix) void setProjectionMatrix(const osg::Matrixf& projectionMatrix)

View file

@ -645,22 +645,14 @@ namespace MWRender
auto& sm = Stereo::Manager::instance(); auto& sm = Stereo::Manager::instance();
auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix"); auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix");
auto projectionMatrix = sm.computeEyeProjection(0, true); auto projectionMatrix = sm.computeEyeProjection(0, true);
auto viewOffsetMatrix = sm.computeEyeViewOffset(0); projectionMatrixUniform->set(projectionMatrix);
for (int col : {0, 1, 2})
viewOffsetMatrix(3, col) = 0;
projectionMatrixUniform->set(viewOffsetMatrix * projectionMatrix);
} }
void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* /*cv*/) override void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* /*cv*/) override
{ {
auto& sm = Stereo::Manager::instance(); auto& sm = Stereo::Manager::instance();
auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix"); auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix");
auto projectionMatrix = sm.computeEyeProjection(1, true); auto projectionMatrix = sm.computeEyeProjection(1, true);
auto viewOffsetMatrix = sm.computeEyeViewOffset(1); projectionMatrixUniform->set(projectionMatrix);
for (int col : {0, 1, 2})
viewOffsetMatrix(3, col) = 0;
projectionMatrixUniform->set(viewOffsetMatrix * projectionMatrix);
} }
private: private:

View file

@ -71,14 +71,14 @@ namespace Stereo
{ {
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix) if (uProjectionMatrix)
uProjectionMatrix->set(mManager->computeEyeViewOffset(0) * mManager->computeEyeProjection(0, SceneUtil::AutoDepth::isReversed())); uProjectionMatrix->set(mManager->computeEyeProjection(0, SceneUtil::AutoDepth::isReversed()));
} }
void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override
{ {
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix) if (uProjectionMatrix)
uProjectionMatrix->set(mManager->computeEyeViewOffset(1) * mManager->computeEyeProjection(1, SceneUtil::AutoDepth::isReversed())); uProjectionMatrix->set(mManager->computeEyeProjection(1, SceneUtil::AutoDepth::isReversed()));
} }
private: private:
@ -245,23 +245,23 @@ namespace Stereo
osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const override osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const override
{ {
(void)projection; (void)projection;
return mManager->computeEyeViewOffset(0) * mManager->computeEyeProjection(0, false); return mManager->computeEyeProjection(0, false);
} }
osg::Matrixd computeLeftEyeView(const osg::Matrixd& view) const override osg::Matrixd computeLeftEyeView(const osg::Matrixd& view) const override
{ {
return view; return view * mManager->computeEyeViewOffset(0);
} }
osg::Matrixd computeRightEyeProjection(const osg::Matrixd& projection) const override osg::Matrixd computeRightEyeProjection(const osg::Matrixd& projection) const override
{ {
(void)projection; (void)projection;
return mManager->computeEyeViewOffset(1) * mManager->computeEyeProjection(1, false); return mManager->computeEyeProjection(1, false);
} }
osg::Matrixd computeRightEyeView(const osg::Matrixd& view) const override osg::Matrixd computeRightEyeView(const osg::Matrixd& view) const override
{ {
return view; return view * mManager->computeEyeViewOffset(1);
} }
Manager* mManager; Manager* mManager;
@ -368,8 +368,8 @@ namespace Stereo
mFrustumManager->update( mFrustumManager->update(
{ {
mViewOffsetMatrix[0] * mProjectionMatrix[0], mProjectionMatrix[0],
mViewOffsetMatrix[1] * mProjectionMatrix[1] mProjectionMatrix[1]
}); });
} }