查看: 2541|回复: 10

osgShadow::pssm的效果怎么这么差

[复制链接]

该用户从未签到

发表于 2014-6-17 14:58:01 | 显示全部楼层 |阅读模式
本帖最后由 casthc 于 2014-9-11 09:37 编辑

osg::ref_ptr<osgShadow:arallelSplitShadowMap> pssm = new osgShadow:arallelSplitShadowMap(NULL,3);
        int res = 1024;
        pssm->setTextureResolution(res);
        root->setShadowTechnique( pssm.get() );
        root->setReceivesShadowTraversalMask( 0x1 );
        root->setCastsShadowTraversalMask( 0x2 );
本来是使用shadowmap,由于产生花斑的原因才使用pssm,但是使用pssm效果更差,表面花斑更多,pssm是sm的升级版,肯定是我那个地方没设置正确,求各位帮忙,非常感谢

该用户从未签到

发表于 2014-6-18 10:35:52 | 显示全部楼层
osgShadow本身就是个试验品,不具有实际应用能力,可以借鉴自己写吧

该用户从未签到

 楼主| 发表于 2014-6-18 10:38:38 | 显示全部楼层
是的shadowMap不行,所以在网上查资料,pssm是一种很好地方法,也读了好几篇文章,理论是明白了,pssm算法在osgShadow库中也已经实现了,但是调用产生的效果极差。。。pssm的osg源代码阅读了n编,感觉没啥参数可调整的。。。。所以才上论坛求助一下

该用户从未签到

发表于 2014-6-25 17:35:56 | 显示全部楼层
osgShadow不是个实验库,很多东西是可以直接用的,也有商业应用的价值。我个人也基于osgShadow实现了目前效果最好的阴影算法,包含了CSM和ESM

shadow map算法有两个不可能攻克的难题,一是projective aliasing,一是perspective aliasing。您这个就属于前者,因为正好有多个面和光照方向完全平行,所以shadow map上的一个light space像素被迫对应了camera space中大量的实际像素,此时花斑是无法避免的。而国际上主流的方法(asm)都难以做到离线

在实际工程中,正确的做法有两种,一是回避这种正好的平行面,二是预处理或者后处理模糊

该用户从未签到

发表于 2014-6-25 17:36:59 | 显示全部楼层
还有shadow map是目前唯一可以做到大规模阴影实现的方法,shadow volume在大场景中就是渣渣。。。
CryEngine就是标准的CSM + ESM的方案

该用户从未签到

 楼主| 发表于 2014-6-26 22:22:19 | 显示全部楼层
array 发表于 2014-6-25 17:36
还有shadow map是目前唯一可以做到大规模阴影实现的方法,shadow volume在大场景中就是渣渣。。。
CryEngi ...

需要实现的是实时光照效果,程序中实时计算太阳位置,并赋于场景光照,预处理和后期处理什么意思?pssm不是能够较好的解决sm的产生的缺陷么?

该用户从未签到

发表于 2014-7-1 08:22:58 | 显示全部楼层
您目前的理解可能还比较浅,不妨阅读一些有关shadow map算法的文献,我推荐原版的《Realtime Shadows》一书。中文版虽然是我翻译的,但是能力和时间都有限,因此质量不是很好

csm(也就是您说的pssm,后者只是csm的一个变种)算法的意义是改善了阴影采样时的信号损失,但是它对于aliasing的问题是毫无贡献的。

后处理的filter比如人们最常用的pcf,还有改进的pcss;预处理的方法就是划时代的vsm,以及后继的esm等。

该用户从未签到

发表于 2014-7-22 21:03:22 | 显示全部楼层
楼主能给出第一张图片的代码吗?最近对阴影比较感兴趣,方便的话发点代码学习下  463506631@qq.com

该用户从未签到

 楼主| 发表于 2014-9-11 09:38:26 | 显示全部楼层
VPBBIT 发表于 2014-7-22 21:03
楼主能给出第一张图片的代码吗?最近对阴影比较感兴趣,方便的话发点代码学习下

#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgShadow/ShadowedScene>
#include <osgShadow/ViewDependentShadowMap>
#include <osgShadow/ViewDependentShadowTechnique>
#include <osgShadow/LightSpacePerspectiveShadowMap>
#include <osgShadow/ShadowMap>
#include <osgShadow/StandardShadowMap>
#include <osgShadow/ShadowTexture>
#include <osgShadow/ShadowVolume>
#include <osgShadow/SoftShadowMap>
#include <osgShadow/ParallelSplitShadowMap>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/Viewer>
#include <osg/Transform>

#include <osg/Light>
#include <osg/LightSource>

#include "CommonFunctions"

void main( int argc, char** argv )
{
    unsigned int rcvShadowMask = 0x1;
    unsigned int castShadowMask = 0x2;
   
    // Set the ground (only receives shadow)
    osg::ref_ptr<osg::MatrixTransform> groundNode = new osg::MatrixTransform;
        groundNode->setMatrix(osg::Matrix::translate(osg::Vec3(0.0,0.0,-10.0)));
        groundNode->addChild( osgDB::readNodeFile("lz.osg") );
    groundNode->setNodeMask( rcvShadowMask);
   


        osg::ref_ptr<osg::MatrixTransform> louNode2 = new osg::MatrixTransform;
        louNode2->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0.0,0.0,1.0)*osg::Matrix::translate(osg::Vec3(0.0,0.0,10.0)));
        louNode2->addChild( osgDB::readNodeFile("1lou.ive") );
        louNode2->setNodeMask( castShadowMask|rcvShadowMask );

        osg::ref_ptr<osg::MatrixTransform> louNode3 = new osg::MatrixTransform;
        louNode3->setMatrix(osg::Matrix::translate(osg::Vec3(-150.0,0.0,100.0)));
        louNode3->addChild( osgDB::readNodeFile("cessna.osg") );
        louNode3->setNodeMask( castShadowMask|rcvShadowMask );

   
        osg::ref_ptr<osgShadow:arallelSplitShadowMap> pssm = new osgShadow::ParallelSplitShadowMap(NULL,3);
        int mapres = 1024;
        pssm->setTextureResolution(mapres);

        osg::ref_ptr<osgShadow::StandardShadowMap> vdsm = new osgShadow::StandardShadowMap;


    // Set shadow node
    osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap;
    //vdsm->setShadowMapProjectionHint( osgShadow::ViewDependentShadowMap::ORTHOGRAPHIC_SHADOW_MAP );
    //vdsm->setBaseShadowTextureUnit( 1 );
   
        osg::ref_ptr<osgShadow::SoftShadowMap> ssm = new osgShadow::SoftShadowMap;
        ssm->setSoftnessWidth(0.0);
        // ssm->setAmbientBias(osg::Vec2(0.7,0.7));//0.5,0.5
        /*float bias = ssm->getBias();
        ssm->setBias(bias*2.0);
*/
        osg::ref_ptr<osgShadow::ShadowVolume> sv = new osgShadow::ShadowVolume;

    osg::ref_ptr<osgShadow::ShadowedScene> shadowRoot = new osgShadow::ShadowedScene;
        osg::ref_ptr<osgShadow::ShadowSettings> ss= new osgShadow::ShadowSettings;
        ss->setShaderHint(osgShadow::ShadowSettings::PROVIDE_VERTEX_AND_FRAGMENT_SHADER);
        shadowRoot->setShadowSettings(ss);
    shadowRoot->setShadowTechnique( sm.get() );
    shadowRoot->setReceivesShadowTraversalMask( rcvShadowMask );
    shadowRoot->setCastsShadowTraversalMask( castShadowMask );
   
        shadowRoot->addChild( groundNode.get() );
        //shadowRoot->addChild( louNode.get() );
        shadowRoot->addChild( louNode2.get() );
        shadowRoot->addChild( louNode3.get() );




        osg::ref_ptr<osg:ight> light = new osg::Light();
        light->setLightNum(0);

        light->setPosition(osg::Vec4(1.0,0.0,1.0,0.0));
        //light->setDirection(osg::Vec3(-1.0,0.0,-1.0));
        light->setAmbient(osg::Vec4(0.0,0.0,0.0,1.0));
        light->setDiffuse(osg::Vec4(1.0,1.0,1.0,1.0));


        osg::ref_ptr<osg::LightSource> lightsource = new osg::LightSource();
        lightsource->setLight(light.get());

        osg::ref_ptr<osg::Light> light1 = new osg::Light();
        light1->setLightNum(1);

        light1->setPosition(osg::Vec4(100.0,0.0,100.0,0.0));
        light1->setAmbient(osg::Vec4(1.0,1.0,1.0,1.0));
        light1->setDiffuse(osg::Vec4(1.0,1.0,1.0,1.0));


        osg::ref_ptr<osg::LightSource> lightsource1 = new osg::LightSource();
        lightsource1->setLight(light1.get());

        sm->setLight(light);
        pssm->setUserLight(light);
        pssm->setPolygonOffset(osg::Vec2(-1.0,-1.0));
        //ssm->setLight(light);
        shadowRoot->addChild( lightsource.get() );
        shadowRoot->addChild( lightsource1.get() );

       
    osg::ref_ptr<osg::Group>root  = new osg::Group;
        root->addChild(shadowRoot);
        root->getOrCreateStateSet()->setMode(GL_LIGHT1,osg::StateAttribute::ON);
        root->getOrCreateStateSet()->setMode(GL_LIGHT0,osg::StateAttribute::ON);
        //root->addChild(lightsource);

    osgViewer::Viewer viewer;
    viewer.setSceneData( root.get() );
        viewer.addEventHandler( new osgViewer::StatsHandler );
        viewer.addEventHandler( new osgViewer::WindowSizeHandler );
        viewer.setCameraManipulator(new osgGA::TrackballManipulator);
        while (!viewer.done())
        {
                viewer.frame();
        }
}


该用户从未签到

发表于 2014-9-12 15:50:57 | 显示全部楼层
咱们论坛里的代码容易出现表情。学习时也是一种乐趣

该用户从未签到

发表于 2015-12-7 18:26:29 | 显示全部楼层
本帖最后由 osgChinaOsg 于 2015-12-7 18:27 编辑

用的基本的osgShadow (shadowMap.cpp) 在场景中生成的阴影中晃动很严重 ,而且最后一条红边 会一前一后移动

同时OSG 的PSSM 不支持点光源和聚光灯,只支持平行光
QQ图片20151207182524.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表