diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index d9a3c9270a..6b12af0e78 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -537,9 +537,6 @@ MWShadowTechnique::ShadowData::ShadowData(MWShadowTechnique::ViewDependentData* bool debug = settings->getDebugDraw(); - // set up texgen - _texgen = new osg::TexGen; - // set up the texture _texture = new osg::Texture2D; @@ -994,8 +991,6 @@ void SceneUtil::MWShadowTechnique::copyShadowMap(osgUtil::CullVisitor& cv, ViewD sdl.push_back(lhs_sd); } - assignTexGenSettings(cv, lhs); - if (lhs->_numValidShadows > 0) { prepareStateSetForRenderingShadow(*lhs, cv.getTraversalNumber()); @@ -1007,13 +1002,6 @@ void SceneUtil::MWShadowTechnique::setCustomFrustumCallback(CustomFrustumCallbac _customFrustumCallback = cfc; } -void SceneUtil::MWShadowTechnique::assignTexGenSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd) -{ - for (const auto& sd : vdd->getShadowDataList()) - { - assignTexGenSettings(&cv, sd->_camera, sd->_textureUnit, sd->_texgen); - } -} void MWShadowTechnique::update(osg::NodeVisitor& nv) { @@ -1035,7 +1023,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) int endUnit = baseUnit + settings->getNumShadowMapsPerLight(); for (int i = baseUnit; i < endUnit; ++i) { - dummyState->setTextureAttributeAndModes(i, _fallbackShadowMapTexture, osg::StateAttribute::ON); + dummyState->setTextureAttribute(i, _fallbackShadowMapTexture, osg::StateAttribute::ON); dummyState->addUniform(new osg::Uniform(("shadowTexture" + std::to_string(i - baseUnit)).c_str(), i)); dummyState->addUniform(new osg::Uniform(("shadowTextureUnit" + std::to_string(i - baseUnit)).c_str(), i)); } @@ -1548,7 +1536,30 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // 4.4 compute main scene graph TexGen + uniform settings + setup state // - assignTexGenSettings(&cv, camera.get(), textureUnit, sd->_texgen.get()); + { + 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; + } + + if (!shadowSpaceUniform) + { + shadowSpaceUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, shadowSpaceUniformName); + _uniforms[cv.getTraversalNumber() % 2].push_back(shadowSpaceUniform); + } + + shadowSpaceUniform->set(shadowSpaceMatrix); + } // mark the light as one that has active shadows and requires shaders pl.textureUnits.push_back(textureUnit); @@ -1556,14 +1567,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) // pass on shadow data to ShadowDataList sd->_textureUnit = textureUnit; - if (textureUnit >= 8) - { - OSG_NOTICE<<"Shadow texture unit is invalid for texgen, will not be used."<setAttributeAndModes(_castingPrograms[GL_ALWAYS - GL_NEVER], osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); // The casting program uses a sampler, so to avoid undefined behaviour, we must bind a dummy texture in case no other is supplied - _shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); + _shadowCastingStateSet->setTextureAttribute(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); _shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); osg::ref_ptr depth = new osg::Depth; @@ -3081,28 +3085,6 @@ bool MWShadowTechnique::adjustPerspectiveShadowMapCameraSettings(osgUtil::Render return true; } -bool MWShadowTechnique::assignTexGenSettings(osgUtil::CullVisitor* cv, osg::Camera* camera, unsigned int textureUnit, osg::TexGen* texgen) -{ - OSG_INFO<<"assignTexGenSettings() textureUnit="<setTextureAttributeAndModes(sd._textureUnit, sd._texture.get(), shadowMapModeValue); - - stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); - stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); - stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); - stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON); + stateset->setTextureAttribute(sd._textureUnit, sd._texture.get(), shadowMapModeValue); } return stateset; @@ -3304,7 +3281,7 @@ void SceneUtil::MWShadowTechnique::DebugHUD::draw(osg::ref_ptr t addAnotherShadowMap(); osg::ref_ptr stateSet = new osg::StateSet(); - stateSet->setTextureAttributeAndModes(sDebugTextureUnit, texture, osg::StateAttribute::ON); + stateSet->setTextureAttribute(sDebugTextureUnit, texture, osg::StateAttribute::ON); auto frustumUniform = mFrustumUniforms[cv.getTraversalNumber() % 2][shadowMapNumber]; frustumUniform->set(matrix); @@ -3317,8 +3294,6 @@ void SceneUtil::MWShadowTechnique::DebugHUD::draw(osg::ref_ptr t mDebugCameras[shadowMapNumber]->accept(cv); cv.popStateSet(); cv.setTraversalMask(traversalMask); - - // cv.getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE); } void SceneUtil::MWShadowTechnique::DebugHUD::releaseGLObjects(osg::State* state) const diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 36cf83c68a..8b39818e2e 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -193,7 +193,6 @@ namespace SceneUtil { unsigned int _textureUnit; osg::ref_ptr _texture; - osg::ref_ptr _texgen; osg::ref_ptr _camera; }; @@ -241,8 +240,6 @@ namespace SceneUtil { void setCustomFrustumCallback(CustomFrustumCallback* cfc); - void assignTexGenSettings(osgUtil::CullVisitor& cv, ViewDependentData* vdd); - virtual void createShaders(); virtual bool selectActiveLights(osgUtil::CullVisitor* cv, ViewDependentData* vdd) const; @@ -255,8 +252,6 @@ namespace SceneUtil { virtual bool adjustPerspectiveShadowMapCameraSettings(osgUtil::RenderStage* renderStage, Frustum& frustum, LightData& positionedLight, osg::Camera* camera, double viewNear, double viewFar); - virtual bool assignTexGenSettings(osgUtil::CullVisitor* cv, osg::Camera* camera, unsigned int textureUnit, osg::TexGen* texgen); - virtual void cullShadowReceivingScene(osgUtil::CullVisitor* cv) const; virtual void cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Camera* camera) const; diff --git a/components/sceneutil/shadow.cpp b/components/sceneutil/shadow.cpp index 702159c3f9..44c0d3d27a 100644 --- a/components/sceneutil/shadow.cpp +++ b/components/sceneutil/shadow.cpp @@ -32,7 +32,7 @@ namespace SceneUtil = std::clamp(Settings::Manager::getInt("number of shadow maps", "Shadows"), 1, 8); mShadowSettings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight); - mShadowSettings->setBaseShadowTextureUnit(8 - numberOfShadowMapsPerLight); + mShadowSettings->setBaseShadowTextureUnit(osg::GLExtensions::Get(0, false)->glMaxTextureUnits - numberOfShadowMapsPerLight); const float maximumShadowMapDistance = Settings::Manager::getFloat("maximum shadow map distance", "Shadows"); if (maximumShadowMapDistance > 0) diff --git a/files/shaders/shadows_vertex.glsl b/files/shaders/shadows_vertex.glsl index f96e1a6735..08daf620bf 100644 --- a/files/shaders/shadows_vertex.glsl +++ b/files/shaders/shadows_vertex.glsl @@ -2,6 +2,7 @@ #if SHADOWS @foreach shadow_texture_unit_index @shadow_texture_unit_list + uniform mat4 shadowSpaceMatrix@shadow_texture_unit_index; uniform int shadowTextureUnit@shadow_texture_unit_index; varying vec4 shadowSpaceCoords@shadow_texture_unit_index; @@ -19,33 +20,28 @@ void setupShadowCoords(vec4 viewPos, vec3 viewNormal) { #if SHADOWS // This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner. - mat4 eyePlaneMat; vec4 shadowOffset; @foreach shadow_texture_unit_index @shadow_texture_unit_list - eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneT[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneR[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneQ[shadowTextureUnit@shadow_texture_unit_index]); - #if @perspectiveShadowMaps shadowRegionCoords@shadow_texture_unit_index = validRegionMatrix@shadow_texture_unit_index * viewPos; #endif - + #if @disableNormalOffsetShadows - shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat; + shadowSpaceCoords@shadow_texture_unit_index = shadowSpaceMatrix@shadow_texture_unit_index * viewPos; #else shadowOffset = vec4(viewNormal * @shadowNormalOffset, 0.0); if (onlyNormalOffsetUV) { - shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat; - vec4 lightSpaceXY = viewPos + shadowOffset; - lightSpaceXY = lightSpaceXY * eyePlaneMat; + lightSpaceXY = shadowSpaceMatrix@shadow_texture_unit_index * lightSpaceXY; shadowSpaceCoords@shadow_texture_unit_index.xy = lightSpaceXY.xy; } else { vec4 offsetViewPosition = viewPos + shadowOffset; - shadowSpaceCoords@shadow_texture_unit_index = offsetViewPosition * eyePlaneMat; + shadowSpaceCoords@shadow_texture_unit_index = shadowSpaceMatrix@shadow_texture_unit_index * offsetViewPosition; } #endif @endforeach