OpenSceneGraph/include/osgShadow/ParallelSplitShadowMap
Robert Osfield 6df0110d0c From Adrian Egli, "update the PSSM, i did some bug fixes and added new features to move the camera virtual against the view direction by applaying a simple distance factor (a), which is calculated camera eye - camera center distance. and we can move the "light camera" against the light direction (b).
(a) some objects behind the camera can cast shadow
(b) object aboive the camera can cast shadow

then i fixed the shadow map orientation, now screen x coordinate alinged which improve the quality"
2007-09-27 12:47:34 +00:00

172 lines
6.3 KiB
C++
Raw Blame History

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
/* ParallelSplitShadowMap written by Adrian Egli */
#ifndef OSGSHADOW_ParallelSplitShadowMap
#define OSGSHADOW_ParallelSplitShadowMap 1
#include <osg/Camera>
#include <osg/Material>
#include <osgShadow/ShadowTechnique>
namespace osgShadow {
class OSGSHADOW_EXPORT ParallelSplitShadowMap : public ShadowTechnique
{
public:
ParallelSplitShadowMap(osg::Geode** debugGroup=NULL, int icountplanes=3);
ParallelSplitShadowMap(const ParallelSplitShadowMap& es, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
META_Object(osgShadow, ParallelSplitShadowMap);
/** Initialize the ShadowedScene and local cached data structures.*/
virtual void init();
/** Run the update traversal of the ShadowedScene and update any loca chached data structures.*/
virtual void update(osg::NodeVisitor& nv);
/** Run the cull traversal of the ShadowedScene and set up the rendering for this ShadowTechnique.*/
virtual void cull(osgUtil::CullVisitor& cv);
/** Clean scene graph from any shadow technique specific nodes, state and drawables.*/
virtual void cleanSceneGraph();
/** Switch on the debug coloring in GLSL (only the first 3 texture/splits showed for visualisation */
inline void setDebugColorOn() { _debug_color_in_GLSL = true; }
/** Set the polygon offset osg::Vec2f(factor,unit) */
inline void setPolygonOffset(const osg::Vec2f& p) { _polgyonOffset = p;_user_polgyonOffset_set=true;}
/** Get the polygon offset osg::Vec2f(factor,unit) */
inline const osg::Vec2f& getPolygonOffset() { return _polgyonOffset;}
/** Set the texture resolution */
inline void setTextureResolution(unsigned int resolution) { _resolution = resolution; }
/** Set the max far distance */
inline void setMaxFarDistance(double farDist) { _setMaxFarDistance = farDist; _isSetMaxFarDistance = true; }
/** Set the factor for moving the virtual camera behind the real camera*/
inline void setMoveVCamBehindRCamFactor(double distFactor ) { _move_vcam_behind_rcam_factor = distFactor; }
/** Force to add a cull face front */
inline void forceFrontCullFace() { _useFrontCullFace = true; }
/** Set min near distance for splits */
inline void setMinNearDistanceForSplits(double nd){ _split_min_near_dist=nd; }
/** use linear split (default: linear) */
inline void useLinearSplit(bool flag) { _linearSplit = flag;}
/**
light / |
\ / |
min near dist / |
for splits / |
\ / <20> |
./ \ <20> |
| \ <20> |
| x <20> |
| <20> |
. | |
\ <20> |
\ <20> |
\ |
\ |
\ |
.<- max far dist. ->.
*/
protected :
virtual ~ParallelSplitShadowMap() {}
std::string generateGLSL_FragmentShader_BaseTex(bool debug, unsigned int splitCount);
struct PSSMShadowSplitTexture {
// RTT
osg::ref_ptr<osg::Camera> _camera;
osg::ref_ptr<osg::TexGen> _texgen;
osg::ref_ptr<osg::Texture2D> _texture;
osg::ref_ptr<osg::StateSet> _stateset;
unsigned int _textureUnit;
osg::Vec2d _ambientBias;
osg::ref_ptr<osg::Camera> _debug_camera;
osg::ref_ptr<osg::Texture2D> _debug_texture;
osg::ref_ptr<osg::StateSet> _debug_stateset;
unsigned int _debug_textureUnit;
// Light (SUN)
osg::Vec3d _lightCameraSource;
osg::Vec3d _lightCameraTarget;
osg::Vec3d _frustumSplitCenter;
osg::Vec3d _lightDirection;
double _lightNear;
double _lightFar;
osg::Matrix _cameraView;
osg::Matrix _cameraProj;
unsigned int _splitID;
unsigned int _resolution;
osg::Uniform* _farDistanceSplit;
};
typedef std::map<unsigned int,PSSMShadowSplitTexture> PSSMShadowSplitTextureMap;
PSSMShadowSplitTextureMap _PSSMShadowSplitTextureMap;
private:
void calculateFrustumCorners(PSSMShadowSplitTexture &pssmShadowSplitTexture,osg::Vec3d *frustumCorners);
void calculateLightInitalPosition(PSSMShadowSplitTexture &pssmShadowSplitTexture,osg::Vec3d *frustumCorners);
void calculateLightNearFarFormFrustum(PSSMShadowSplitTexture &pssmShadowSplitTexture,osg::Vec3d *frustumCorners);
void calculateLightViewProjectionFormFrustum(PSSMShadowSplitTexture &pssmShadowSplitTexture,osg::Vec3d *frustumCorners);
osg::Geode** _displayTexturesGroupingNode;
unsigned int _textureUnitOffset;
unsigned int _number_of_splits;
bool _debug_color_in_GLSL;
osg::Vec2f _polgyonOffset;
bool _user_polgyonOffset_set;
unsigned int _resolution;
double _setMaxFarDistance;
bool _isSetMaxFarDistance;
bool _useFrontCullFace;
double _split_min_near_dist;
double _move_vcam_behind_rcam_factor;
bool _linearSplit;
};
}
#endif