[osg-users] Fwd: Strange osgShadow appearance of multiple models self-shadowing under a point light
Bris Li
tqjxlm at gmail.com
Tue Jun 27 09:14:53 PDT 2017
Hi all,
It's a problem with osgShadow.
I hava a scene with multiple pagedLOD models bundled in a group. The models
are tiles of a city, and each tile is a single model (buildings are not
separeted with terrain).
I uses the code in the osgShadow example for shadowing, and put a point
light in _shadowedScene. The models shadow on themselves.
As the attached image shows, the shadow result is partially correct. In
some particular angle range from the light source, the correct shadow is
casted. But in the other range, shadow is not cast correctly, but some
strange shadows appear which I guess is casted from the model at the other
side.
Also, if I put the light on one side of the building, the other side of it
is still lit, no shadow showing.
I have tried different shadow implementations, but the results remain
almost the same.
I can't figure out what is happening since the shadow is just 'partially'
abnormal. Stuck here for days.
Thanks.
Regards,
tqjxlm.
osg version 3.4.0.
code:
------------------------------------------------------------
------------------------------------------------------------
---------------------------------------------
*Shadow*
// arguments
char* argv[] = {
"--vdsm",
"--positionalLight",
"--ortho",
"--parallel-split",
"--num-sm",
"4",
"--cascaded"
};
int argc = sizeof(argv) / sizeof(argv[0]);
// use an ArgumentParser object to manage the program arguments
osg::ArgumentParser arguments(&argc, argv);
// get the viewer
osgViewer::View& viewer = getViewer();
// init shadowed scene
_shadowedScene = new osgShadow::ShadowedScene;
osgShadow::ShadowSettings* settings = _shadowedScene->getShadowSettings();
settings->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask);
settings->setCastsShadowTraversalMask(CastsShadowTraversalMask);
double distance;
if (arguments.read("--max-shadow-distance", distance))
{
settings->setMaximumShadowMapDistance(distance);
}
// choose shadow map implementation
osg::ref_ptr<osgShadow::MinimalShadowMap> msm = NULL;
if (arguments.read("--no-shadows"))
{
OSG_NOTICE << "Not using a ShadowTechnique" << std::endl;
_shadowedScene->setShadowTechnique(0);
}
else if (arguments.read("--stsm"))
{
osg::ref_ptr<osgShadow::StandardShadowMap> st = new
osgShadow::StandardShadowMap;
_shadowedScene->setShadowTechnique(st.get());
}
else if (arguments.read("--pssm"))
{
int mapcount = 3;
while (arguments.read("--mapcount", mapcount));
osg::ref_ptr<osgShadow::ParallelSplitShadowMap> pssm = new
osgShadow::ParallelSplitShadowMap(NULL, mapcount);
int mapres = 1024;
while (arguments.read("--mapres", mapres))
pssm->setTextureResolution(mapres);
while (arguments.read("--debug-color")) { pssm->setDebugColorOn(); }
int minNearSplit = 0;
while (arguments.read("--minNearSplit", minNearSplit))
if (minNearSplit > 0) {
pssm->setMinNearDistanceForSplits(minNearSplit);
}
int maxfardist = 0;
while (arguments.read("--maxFarDist", maxfardist))
if (maxfardist > 0) {
pssm->setMaxFarDistance(maxfardist);
std::cout << "ParallelSplitShadowMap : setMaxFarDistance(" << maxfardist <<
")" << std::endl;
}
int moveVCamFactor = 0;
while (arguments.read("--moveVCamFactor", moveVCamFactor))
if (maxfardist > 0) {
pssm->setMoveVCamBehindRCamFactor(moveVCamFactor);
}
double polyoffsetfactor = pssm->getPolygonOffset().x();
double polyoffsetunit = pssm->getPolygonOffset().y();
while (arguments.read("--PolyOffset-Factor", polyoffsetfactor));
while (arguments.read("--PolyOffset-Unit", polyoffsetunit));
pssm->setPolygonOffset(osg::Vec2(polyoffsetfactor, polyoffsetunit));
_shadowedScene->setShadowTechnique(pssm.get());
}
else if (arguments.read("--ssm"))
{
osg::ref_ptr<osgShadow::SoftShadowMap> sm = new osgShadow::SoftShadowMap;
_shadowedScene->setShadowTechnique(sm.get());
}
else if (arguments.read("--vdsm"))
{
while (arguments.read("--debugHUD")) settings->setDebugDraw(true);
if (arguments.read("--persp")) settings->setShadowMapProjecti
onHint(osgShadow::ShadowSettings::PERSPECTIVE_SHADOW_MAP);
if (arguments.read("--ortho")) settings->setShadowMapProjecti
onHint(osgShadow::ShadowSettings::ORTHOGRAPHIC_SHADOW_MAP);
unsigned int unit = 1;
if (arguments.read("--unit", unit)) settings->setBaseShadowTexture
Unit(unit);
double n = 0.0;
if (arguments.read("-n", n)) settings->setMinimumShadowMapNearFarRatio(n);
unsigned int numShadowMaps;
if (arguments.read("--num-sm", numShadowMaps))
settings->setNumShadowMapsPerLight(numShadowMaps);
if (arguments.read("--parallel-split") || arguments.read("--ps"))
settings->setMultipleShadowMapHint(osgShadow::ShadowSettings::PARALLEL_
SPLIT);
if (arguments.read("--cascaded")) settings->setMultipleShadowMap
Hint(osgShadow::ShadowSettings::CASCADED);
int mapres = 1024;
while (arguments.read("--mapres", mapres))
settings->setTextureSize(osg::Vec2s(mapres, mapres));
osg::ref_ptr<osgShadow::ViewDependentShadowMap> vdsm = new
osgShadow::ViewDependentShadowMap;
_shadowedScene->setShadowTechnique(vdsm.get());
}
else if (arguments.read("--lispsm"))
{
if (arguments.read("--ViewBounds"))
msm = new osgShadow::LightSpacePerspectiveShadowMapVB;
else if (arguments.read("--CullBounds"))
msm = new osgShadow::LightSpacePerspectiveShadowMapCB;
else // if( arguments.read( "--DrawBounds" ) ) // default
msm = new osgShadow::LightSpacePerspectiveShadowMapDB;
}
else if (arguments.read("--msm"))
{
if (arguments.read("--ViewBounds"))
msm = new osgShadow::MinimalShadowMap;
else if (arguments.read("--CullBounds"))
msm = new osgShadow::MinimalCullBoundsShadowMap;
else // if( arguments.read( "--DrawBounds" ) ) // default
msm = new osgShadow::MinimalDrawBoundsShadowMap;
}
else /* if (arguments.read("--sm")) */
{
osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap;
_shadowedScene->setShadowTechnique(sm.get());
int mapres = 1024;
while (arguments.read("--mapres", mapres))
sm->setTextureSize(osg::Vec2s(mapres, mapres));
}
if (msm)// Set common MSM & LISPSM arguments
{
_shadowedScene->setShadowTechnique(msm.get());
while (arguments.read("--debugHUD")) msm->setDebugDraw(true);
float minLightMargin = 10.f;
float maxFarPlane = 0;
unsigned int texSize = 1024;
unsigned int baseTexUnit = 0;
unsigned int shadowTexUnit = 1;
while (arguments.read("--moveVCamFactor", minLightMargin));
while (arguments.read("--minLightMargin", minLightMargin));
while (arguments.read("--maxFarDist", maxFarPlane));
while (arguments.read("--mapres", texSize));
while (arguments.read("--baseTextureUnit", baseTexUnit));
while (arguments.read("--shadowTextureUnit", shadowTexUnit));
msm->setMinLightMargin(minLightMargin);
msm->setMaxFarPlane(maxFarPlane);
msm->setTextureSize(osg::Vec2s(texSize, texSize));
msm->setShadowTextureCoordIndex(shadowTexUnit);
msm->setShadowTextureUnit(shadowTexUnit);
msm->setBaseTextureCoordIndex(baseTexUnit);
msm->setBaseTextureUnit(baseTexUnit);
}
// init light
osg::Vec4 lightpos(0.0, 0.0, 1, 0.0);
bool spotlight = false;
while (arguments.read("--positionalLight")) { lightpos.set(0.5, 0.5, 1.5,
1.0); }
while (arguments.read("--directionalLight")) { lightpos.set(0.0, 0.0, 1,
0.0); }
while (arguments.read("--spotLight")) { lightpos.set(0.5, 0.5, 1.5, 1.0);
spotlight = true; }
// set light position, create a light ball for visualization
osg::ref_ptr<osg::Geode> coord = createIndicator(_intersectedPoint);
_lsIndicator = dynamic_cast<osg::ShapeDrawable*>(coord->getDrawable(0));
_worldRoot->addChild(coord);
_ls = new osg::LightSource;
_ls->getLight()->setPosition(lightpos);
_ls->getLight()->setAmbient(osg::Vec4(0.7, 0.7, 0.7, 1.0));
_ls->getLight()->setDiffuse(osg::Vec4(0.8, 0.8, 0.8, 1.0));
// set shadowed model
_model = _loadedModels;
_nodeMask = _model->getNodeMask();
_model->setNodeMask(_nodeMask | CastsShadowTraversalMask |
ReceivesShadowTraversalMask);
_shadowedScene->addChild(_model.get());
_shadowedScene->addChild(_ls.get());
_root->addChild(_shadowedScene);
------------------------------------------------------------
------------------------------------------------------------
---------------------------------------------
*View initialization*
osg::StateSet* state = _root->getOrCreateStateSet();
state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
osg::Camera* camera = view->getCamera();
camera->setGraphicsContext( gw );
const osg::GraphicsContext::Traits* traits = gw->getTraits();
camera->setClearColor( osg::Vec4(1.0, 1.0, 1.0, 1.0) );
camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height)
);
camera->setProjectionMatrixAsPerspective(
30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height),
0.1f, 100000.0f );
camera->setComputeNearFarMode(osg::Camera::COMPUTE_NEAR_FAR_
USING_BOUNDING_VOLUMES);
camera->setNearFarRatio(0.000002);
GLuint buffer = gw->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setReadBuffer(buffer);
camera->setDrawBuffer(buffer);
view->setSceneData( scene );
view->addEventHandler(new osgViewer::StatsHandler);
view->addEventHandler(new osgViewer::ThreadingHandler);
view->addEventHandler(new osgViewer::WindowSizeHandler);
view->addEventHandler(new osgViewer::LODScaleHandler);
------------------------------------------------------------
------------------------------------------------------------
---------------------------------------------
And the screen shots:
Strange shadow on a square.
No shadow of the flag.
Change light position, flag is shadowed correctly.
Light on a build wall.
The back side should not be lit.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20170628/6f01bb52/attachment-0001.htm>
More information about the osg-users
mailing list