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:
parent
a2f5e1c075
commit
ea51c55d00
2 changed files with 89 additions and 49 deletions
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue