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

Restore valid per view shadow settings.

This commit is contained in:
Mads Buvik Sandvei 2025-01-18 16:11:47 +01:00
parent a2f5e1c075
commit ea51c55d00
2 changed files with 89 additions and 49 deletions

View file

@ -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<osg::Uniform> 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<osg::Uniform> 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<osg::Uniform> 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<osg::Uniform> 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()"<<std::endl;
@ -3128,6 +3154,12 @@ osg::StateSet* MWShadowTechnique::prepareStateSetForRenderingShadow(ViewDependen
stateset->addUniform(uniform);
}
for(const auto& uniform : vdd._uniforms[traversalNumber % 2])
{
OSG_INFO<<"addUniform("<<uniform->getName()<<")"<<std::endl;
stateset->addUniform(uniform);
}
if (_program.valid())
{
stateset->setAttribute(_program.get());

View file

@ -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<osg::Uniform> > Uniforms;
// forward declare
class ViewDependentData;
@ -192,6 +193,7 @@ namespace SceneUtil {
ViewDependentData* _viewDependentData;
unsigned int _textureUnit;
unsigned int _sm_i;
osg::ref_ptr<osg::Texture2D> _texture;
osg::ref_ptr<osg::Camera> _camera;
};
@ -228,6 +230,7 @@ namespace SceneUtil {
LightDataList _lightDataList;
ShadowDataList _shadowDataList;
std::array<Uniforms, 2> _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<osg::Plane>& 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<osg::Texture2D> _fallbackBaseTexture;
osg::ref_ptr<osg::Texture2D> _fallbackShadowMapTexture;
typedef std::vector< osg::ref_ptr<osg::Uniform> > Uniforms;
std::array<Uniforms, 2> _uniforms;
osg::ref_ptr<osg::Program> _program;