1
0
Fork 0

Make the number of shadow cascades and the range of each configurable

This commit is contained in:
Frederic Bouvier 2012-04-17 09:10:53 +02:00
parent f1ad01478e
commit 7d3195aaa6
2 changed files with 93 additions and 12 deletions

View file

@ -414,12 +414,20 @@ FGRenderer::FGRenderer() :
_sunDirection( new osg::Uniform( "fg_SunDirection", osg::Vec3f() ) ),
_planes( new osg::Uniform( "fg_Planes", osg::Vec3f() ) ),
_fogColor( new osg::Uniform( "fg_FogColor", osg::Vec4f(1.0, 1.0, 1.0, 1.0) ) ),
_fogDensity( new osg::Uniform( "fg_FogDensity", 0.0001f ) )
_fogDensity( new osg::Uniform( "fg_FogDensity", 0.0001f ) ),
_shadowNumber( new osg::Uniform( "fg_ShadowNumber", (int)4 ) ),
_shadowDistances( new osg::Uniform( "fg_ShadowDistances", osg::Vec4f(5.0, 50.0, 500.0, 5000.0 ) ) )
{
#ifdef FG_JPEG_SERVER
jpgRenderFrame = updateRenderer;
#endif
eventHandler = new FGEventHandler;
_numCascades = 4;
_cascadeFar[0] = 5.f;
_cascadeFar[1] = 50.f;
_cascadeFar[2] = 500.f;
_cascadeFar[3] = 5000.f;
}
FGRenderer::~FGRenderer()
@ -474,13 +482,38 @@ public:
}
};
class ShadowNumListener : public SGPropertyChangeListener {
public:
virtual void valueChanged(SGPropertyNode* node) {
globals->get_renderer()->updateCascadeNumber(node->getIntValue());
}
};
class ShadowRangeListener : public SGPropertyChangeListener {
public:
virtual void valueChanged(SGPropertyNode* node) {
globals->get_renderer()->updateCascadeFar(node->getIndex(), node->getFloatValue());
}
};
void
FGRenderer::init( void )
{
_classicalRenderer = !fgGetBool("/sim/rendering/rembrandt", false);
_classicalRenderer = !fgGetBool("/sim/rendering/rembrandt", false);
_shadowMapSize = fgGetInt( "/sim/rendering/shadows/map-size", 4096 );
fgAddChangeListener( new ShadowMapSizeListener, "/sim/rendering/shadows/map-size" );
fgAddChangeListener( new ShadowEnabledListener, "/sim/rendering/shadows/enabled" );
ShadowRangeListener* srl = new ShadowRangeListener;
fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[0]");
fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[1]");
fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[2]");
fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[3]");
fgAddChangeListener(new ShadowNumListener, "/sim/rendering/shadows/num-cascades");
_numCascades = fgGetInt("/sim/rendering/shadows/num-cascades", 4);
_cascadeFar[0] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[0]", 5.0f);
_cascadeFar[1] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[1]", 50.0f);
_cascadeFar[2] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[2]", 500.0f);
_cascadeFar[3] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[3]", 5000.0f);
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
_scenery_override = fgGetNode("/sim/sceneryloaded-override", true);
_panel_hotspots = fgGetNode("/sim/panel-hotspots", true);
@ -895,10 +928,34 @@ void FGRenderer::updateShadowCamera(const flightgear::CameraInfo* info, const os
camera->getProjectionMatrix().getFrustum(left,right,bottom,top,zNear,zFar);
shadowSwitch->setAllChildrenOn();
updateShadowCascade(info, camera, shadowSwitch, 0, left, right, bottom, top, zNear, 1.0, 5.0/zNear);
updateShadowCascade(info, camera, shadowSwitch, 1, left, right, bottom, top, zNear, 5.0/zNear, 50.0/zNear);
updateShadowCascade(info, camera, shadowSwitch, 2, left, right, bottom, top, zNear, 50.0/zNear, 512.0/zNear);
updateShadowCascade(info, camera, shadowSwitch, 3, left, right, bottom, top, zNear, 512.0/zNear, 5000.0/zNear);
if (_numCascades == 1) {
osg::Camera* cascadeCam = static_cast<osg::Camera*>( shadowSwitch->getChild(0) );
cascadeCam->setViewport( 0, 0, _shadowMapSize, _shadowMapSize );
} else {
for (int no = 0; no < 4; ++no) {
osg::Camera* cascadeCam = static_cast<osg::Camera*>( shadowSwitch->getChild(no) );
cascadeCam->setViewport( int( no / 2 ) * (_shadowMapSize/2), (no & 1) * (_shadowMapSize/2), (_shadowMapSize/2), (_shadowMapSize/2) );
}
}
updateShadowCascade(info, camera, shadowSwitch, 0, left, right, bottom, top, zNear, 1.0, _cascadeFar[0]/zNear);
if (_numCascades > 1) {
shadowSwitch->setValue(1, true);
updateShadowCascade(info, camera, shadowSwitch, 1, left, right, bottom, top, zNear, _cascadeFar[0]/zNear, _cascadeFar[1]/zNear);
} else {
shadowSwitch->setValue(1, false);
}
if (_numCascades > 2) {
shadowSwitch->setValue(2, true);
updateShadowCascade(info, camera, shadowSwitch, 2, left, right, bottom, top, zNear, _cascadeFar[1]/zNear, _cascadeFar[2]/zNear);
} else {
shadowSwitch->setValue(2, false);
}
if (_numCascades > 3) {
shadowSwitch->setValue(3, true);
updateShadowCascade(info, camera, shadowSwitch, 3, left, right, bottom, top, zNear, _cascadeFar[2]/zNear, _cascadeFar[3]/zNear);
} else {
shadowSwitch->setValue(3, false);
}
{
osg::Matrixd &viewMatrix = mainShadowCamera->getViewMatrix();
@ -980,6 +1037,23 @@ void FGRenderer::enableShadows(bool enabled)
}
}
void FGRenderer::updateCascadeFar(int index, float far_m)
{
if (index < 0 || index > 3)
return;
_cascadeFar[index] = far_m;
_shadowDistances->set( osg::Vec4f(_cascadeFar[0], _cascadeFar[1], _cascadeFar[2], _cascadeFar[3]) );
}
void FGRenderer::updateCascadeNumber(size_t num)
{
if (num < 1 || num > 4)
return;
_numCascades = num;
_shadowNumber->set( (int)_numCascades );
}
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
@ -1199,6 +1273,8 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in
ss->addUniform( _sunSpecular );
ss->addUniform( _sunDirection );
ss->addUniform( _planes );
ss->addUniform( _shadowNumber );
ss->addUniform( _shadowDistances );
osg::Geometry* g = osg::createTexturedQuadGeometry( osg::Vec3(-1.,-1.,0.), osg::Vec3(2.,0.,0.), osg::Vec3(0.,2.,0.) );
g->setUseDisplayList(false);

View file

@ -109,6 +109,8 @@ public:
void updateShadowCamera(const flightgear::CameraInfo* info, const osg::Vec3d& position);
void updateShadowMapSize(int mapSize);
void enableShadows(bool enabled);
void updateCascadeFar(int index, float far_m);
void updateCascadeNumber(size_t num);
SGSky* getSky() const { return _sky; }
@ -131,22 +133,25 @@ protected:
SGPropertyNode_ptr _virtual_cockpit;
SGTimeStamp _splash_time;
SGSky* _sky;
bool _classicalRenderer;
bool _classicalRenderer;
int _shadowMapSize;
size_t _numCascades;
float _cascadeFar[4];
osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
void updateShadowCascade(const flightgear::CameraInfo* info, osg::Camera* camera, osg::Group* grp, int idx, double left, double right, double bottom, double top, double zNear, double f1, double f2);
osg::Vec3 getSunDirection() const;
osg::ref_ptr<osg::Uniform> _ambientFactor;
osg::ref_ptr<osg::Uniform> _ambientFactor;
osg::ref_ptr<osg::Uniform> _sunDiffuse;
osg::ref_ptr<osg::Uniform> _sunSpecular;
osg::ref_ptr<osg::Uniform> _sunDirection;
osg::ref_ptr<osg::Uniform> _planes;
osg::ref_ptr<osg::Uniform> _fogColor;
osg::ref_ptr<osg::Uniform> _fogDensity;
osg::ref_ptr<osg::Uniform> _shadowNumber;
osg::ref_ptr<osg::Uniform> _shadowDistances;
};
bool fgDumpSceneGraphToFile(const char* filename);