From ea51c55d007c9d070950a9b4d610b9148d580051 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Sat, 18 Jan 2025 16:11:47 +0100 Subject: [PATCH] Restore valid per view shadow settings. --- components/sceneutil/mwshadowtechnique.cpp | 128 +++++++++++++-------- components/sceneutil/mwshadowtechnique.hpp | 10 +- 2 files changed, 89 insertions(+), 49 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 9fd435f40d..929ffadcbf 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -986,9 +986,12 @@ void SceneUtil::MWShadowTechnique::copyShadowMap(osgUtil::CullVisitor& cv, ViewD lhs_sd->_camera = rhs_sd->_camera; lhs_sd->_textureUnit = rhs_sd->_textureUnit; lhs_sd->_texture = rhs_sd->_texture; + lhs_sd->_sm_i = rhs_sd->_sm_i; sdl.push_back(lhs_sd); } + copyShadowStateSettings(cv, lhs); + if (lhs->_numValidShadows > 0) { prepareStateSetForRenderingShadow(*lhs, cv.getTraversalNumber()); @@ -1000,6 +1003,15 @@ void SceneUtil::MWShadowTechnique::setCustomFrustumCallback(CustomFrustumCallbac _customFrustumCallback = cfc; } +void SceneUtil::MWShadowTechnique::copyShadowStateSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd) +{ + for (const auto& sd : vdd->getShadowDataList()) + { + //assignTexGenSettings(&cv, sd->_camera, sd->_textureUnit, sd->_texgen); + assignValidRegionSettings(cv, sd->_camera, sd->_sm_i, vdd->_uniforms[cv.getTraversalNumber()%2]); + assignShadowStateSettings(cv, sd->_camera, sd->_sm_i, vdd->_uniforms[cv.getTraversalNumber()%2]); + } +} void MWShadowTechnique::update(osg::NodeVisitor& nv) { @@ -1053,6 +1065,8 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) _shadowedScene->osg::Group::traverse(cv); return; } + + Uniforms& vddUniforms = vdd->_uniforms[cv.getTraversalNumber() % 2]; ShadowSettings* settings = getShadowedScene()->getShadowSettings(); @@ -1498,31 +1512,10 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) cv.popStateSet(); + if (!orthographicViewFrustum && settings->getShadowMapProjectionHint()==ShadowSettings::PERSPECTIVE_SHADOW_MAP) { - { - osg::Matrix validRegionMatrix = cv.getCurrentCamera()->getInverseViewMatrix() * camera->getViewMatrix() * camera->getProjectionMatrix(); - - std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i); - osg::ref_ptr validRegionUniform; - - for (const auto & uniform : _uniforms[cv.getTraversalNumber() % 2]) - { - if (uniform->getName() == validRegionUniformName) - { - validRegionUniform = uniform; - break; - } - } - - if (!validRegionUniform) - { - validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName); - _uniforms[cv.getTraversalNumber() % 2].push_back(validRegionUniform); - } - - validRegionUniform->set(validRegionMatrix); - } + assignValidRegionSettings(cv, camera, sm_i, vddUniforms); if (settings->getMultipleShadowMapHint() == ShadowSettings::CASCADED) adjustPerspectiveShadowMapCameraSettings(vdsmCallback->getRenderStage(), frustum, pl, camera.get(), cascaseNear, cascadeFar); @@ -1537,31 +1530,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // 4.4 compute main scene graph TexGen + uniform settings + setup state // { - osg::Matrix shadowSpaceMatrix = cv.getCurrentCamera()->getInverseViewMatrix() * - camera->getViewMatrix() * - camera->getProjectionMatrix() * - osg::Matrix::translate(1.0,1.0,1.0) * - osg::Matrix::scale(0.5,0.5,0.5); - - std::string shadowSpaceUniformName = "shadowSpaceMatrix" + std::to_string(sm_i); - osg::ref_ptr shadowSpaceUniform; - - for (const auto & uniform : _uniforms[cv.getTraversalNumber() % 2]) - { - if (uniform->getName() == shadowSpaceUniformName) - { - shadowSpaceUniform = uniform; - break; - } - } - - if (!shadowSpaceUniform) - { - shadowSpaceUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, shadowSpaceUniformName); - _uniforms[cv.getTraversalNumber() % 2].push_back(shadowSpaceUniform); - } - - shadowSpaceUniform->set(shadowSpaceMatrix); + assignShadowStateSettings(cv, camera, sm_i, vddUniforms); } // mark the light as one that has active shadows and requires shaders @@ -1569,6 +1538,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // pass on shadow data to ShadowDataList sd->_textureUnit = textureUnit; + sd->_sm_i = sm_i; sdl.push_back(sd); @@ -3080,6 +3050,62 @@ bool MWShadowTechnique::adjustPerspectiveShadowMapCameraSettings(osgUtil::Render return true; } +void MWShadowTechnique::assignShadowStateSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms) +{ + osg::Matrix inverseViewMatrix = osg::Matrix::inverse(*cv.getModelViewMatrix()); + osg::Matrix shadowSpaceMatrix = inverseViewMatrix * + camera->getViewMatrix() * + camera->getProjectionMatrix() * + osg::Matrix::translate(1.0,1.0,1.0) * + osg::Matrix::scale(0.5,0.5,0.5); + + std::string shadowSpaceUniformName = "shadowSpaceMatrix" + std::to_string(sm_i); + osg::ref_ptr shadowSpaceUniform; + + for (const auto & uniform : uniforms) + { + if (uniform->getName() == shadowSpaceUniformName) + { + shadowSpaceUniform = uniform; + break; + } + } + + if (!shadowSpaceUniform) + { + shadowSpaceUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, shadowSpaceUniformName); + uniforms.push_back(shadowSpaceUniform); + } + + shadowSpaceUniform->set(shadowSpaceMatrix); + return; +} + +void SceneUtil::MWShadowTechnique::assignValidRegionSettings(osgUtil::CullVisitor & cv, osg::Camera* camera, unsigned int sm_i, Uniforms & uniforms) +{ + osg::Matrix validRegionMatrix = osg::Matrix::inverse(*cv.getModelViewMatrix()) * camera->getViewMatrix() * camera->getProjectionMatrix(); + + std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i); + osg::ref_ptr validRegionUniform; + + for (const auto & uniform : uniforms) + { + if (uniform->getName() == validRegionUniformName) + { + validRegionUniform = uniform; + break; + } + } + + if (!validRegionUniform) + { + validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName); + uniforms.push_back(validRegionUniform); + } + + validRegionUniform->set(validRegionMatrix); +} + void MWShadowTechnique::cullShadowReceivingScene(osgUtil::CullVisitor* cv) const { OSG_INFO<<"cullShadowReceivingScene()"<addUniform(uniform); } + for(const auto& uniform : vdd._uniforms[traversalNumber % 2]) + { + OSG_INFO<<"addUniform("<getName()<<")"<addUniform(uniform); + } + if (_program.valid()) { stateset->setAttribute(_program.get()); diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 8b39818e2e..4b9de9364a 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -157,6 +157,7 @@ namespace SceneUtil { * the resulting shadow map may be invalid. */ virtual void operator()(osgUtil::CullVisitor& cv, osg::BoundingBoxd& customClipSpace, osgUtil::CullVisitor*& sharedFrustumHint) = 0; }; + typedef std::vector< osg::ref_ptr > Uniforms; // forward declare class ViewDependentData; @@ -192,6 +193,7 @@ namespace SceneUtil { ViewDependentData* _viewDependentData; unsigned int _textureUnit; + unsigned int _sm_i; osg::ref_ptr _texture; osg::ref_ptr _camera; }; @@ -228,6 +230,7 @@ namespace SceneUtil { LightDataList _lightDataList; ShadowDataList _shadowDataList; + std::array _uniforms; unsigned int _numValidShadows; }; @@ -240,6 +243,8 @@ namespace SceneUtil { void setCustomFrustumCallback(CustomFrustumCallback* cfc); + void copyShadowStateSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd); + virtual void createShaders(); virtual bool selectActiveLights(osgUtil::CullVisitor* cv, ViewDependentData* vdd) const; @@ -251,6 +256,10 @@ namespace SceneUtil { virtual bool cropShadowCameraToMainFrustum(Frustum& frustum, osg::Camera* camera, double viewNear, double viewFar, std::vector& planeList); virtual bool adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera, double viewNear, double viewFar); + + virtual void assignShadowStateSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms); + + virtual void assignValidRegionSettings(osgUtil::CullVisitor& cv, osg::Camera* camera, unsigned int sm_i, Uniforms& uniforms); virtual void cullShadowReceivingScene(osgUtil::CullVisitor* cv) const; @@ -280,7 +289,6 @@ namespace SceneUtil { osg::ref_ptr _fallbackBaseTexture; osg::ref_ptr _fallbackShadowMapTexture; - typedef std::vector< osg::ref_ptr > Uniforms; std::array _uniforms; osg::ref_ptr _program;