查看: 2959|回复: 12

关于多相机渲染场景的问题?

[复制链接]

该用户从未签到

发表于 2012-10-22 14:07:39 | 显示全部楼层 |阅读模式
如题:
问题描述:我想用单视图多相机渲染场景。其中主相机maincamera(漫游相机)渲染大部分的场景,另外建了一个相机skycamera,专门用来渲染天空盒。愿想是两个相机综合渲染出来的效果跟一个相机渲染出来的效果一样就好!可是问题出现了,不知道什么原因,相机渲染出来的效果是:用skycamera单独渲染天空盒失败,最后只剩下主相机渲染的东西了,天空盒被主相机里边的osg的蓝色背景所覆盖了。导致渲染出来的场景没有了天空。我设置了天空盒相机的渲染顺序是pre_render,应该是先于主相机渲染的。不知道是什么原因导致天空渲染失败了。还是不能用多个相机渲染同一个场景呢?
相关代码:
        天空盒相机:
        m_pSkyDome = new SkyDome( 1900.f, 16, 16,sky_type);
        m_pCamera->addChild(m_pSkyDome);
        m_pCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        m_pCamera->setViewMatrix(osg::Matrix::identity());
        m_pCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
        m_pCamera->setRenderOrder(osg::Camera:RE_RENDER);
        m_pRoot->addChild( m_pCamera );
         
           主相机:
        osg::ref_ptr<TravelManipulator> mainCamera =new TravelManipulator(physicsMgr,viewer);//TravelManipulator是一个漫游相机操作类,class TravelManipulator:public osgGA::MatrixManipulator  
        viewer->setCameraManipulator(mainCamera);

                viewer->setSceneData( m_pRoot );
主相机没有别的什么设置。m_pRoot是场景的根节点,所有的要渲染的实体都在其下边,也包括原来的天空盒。
现在我将天空盒加在了一个创建的相机下边,然后相机挂在了场景根节点下边,不知道这里边的逻辑是否有错。还请大哥们指导,非常感谢!!!!

该用户从未签到

发表于 2012-10-22 16:02:44 | 显示全部楼层
主相机把colorbuffer 从新刷了 当然precamera 渲染的没有了 设置主摄像机的setClearMask为深度就行了

该用户从未签到

 楼主| 发表于 2012-10-22 21:40:13 | 显示全部楼层
liuzhiyu123 发表于 2012-10-22 16:02
主相机把colorbuffer 从新刷了 当然precamera 渲染的没有了 设置主摄像机的setClearMask为深度就行了

非常感谢!现在确实是可以单独渲染出天空了,可是又有了一个新的问题!就是场景里边的树叶为什么会像眨眼皮一样的闪烁呢???而且树叶还会出现严重的天空白边现象!如图:
树叶白边.jpg
这个是怎么回事呢?有没有比较完美的解决办法?非常感谢,折腾我好长时间了,就是不知道怎么弄,什么serRenderHint设置遍了,难道真的是跟很多的树叶打成一组有关系??这次是根据相机,单独设置天空渲染相机的renderorder,还是不能解决问题啊!树叶就是出现天空盒贴图的白边,无语啊!!!!

该用户从未签到

发表于 2012-10-29 09:47:11 | 显示全部楼层
我看不懂您要表述什么,也不知道您用了什么方法。只能说同样的思路,我自己的场景里天空和树的结合反正是很好的~~

该用户从未签到

 楼主| 发表于 2012-10-30 09:45:35 | 显示全部楼层
array 发表于 2012-10-29 09:47
我看不懂您要表述什么,也不知道您用了什么方法。只能说同样的思路,我自己的场景里天空和树的结合反正是很 ...

           看来我表达不够明确啊!是这样的array大哥,我的程序里边以前没有两个相机,只有一个主相机。主要是利用主相机渲染天空和树木等场景。但是渲染出来的情况是树叶的边缘总是有一圈天空盒的纹理白边(如上图所示),而且树叶与树叶的一些交叠地方会出现很明显的闪烁。后来,您给我回帖提到了设置相机的渲染顺序,所以我就想到了重新定义一个相机,单独去渲染后边的天空盒,然后设置这个相机的渲染顺序为pre_render,刚开始因为一些东西没考虑到,所以出现天空盒没有了的情况,但是后来这个问题解决了。就是主相机用来渲染除天空盒以外的场景,另外一个相机用来单独渲染天空盒,并且设置它率先渲染。可是出来的结果还是跟最初的用一个相机渲染所有场景(包括天空盒)一样,树叶的边缘会出现严重的白边(所谓的白边就是天空盒的纹理贴图的白色)。也就是说,我用另外一个相机单独渲染天空并且设置这个相机的渲染顺序为最先渲染还是没有解决树叶的白边问题。不明白为什么后边的天空盒为什么会影响树叶的渲染呢?树叶的边缘硬是有一圈天空盒的白色纹理。(如果天空盒是灰色,树叶的边缘则是灰色的!)我的天空盒是用的是osgocean里边的skydome做的,没有什么特别的修改!
      不好意思,array大哥,还得麻烦您能帮忙指点一下!给个方向或者想法就可以,我可以去尝试一下,有些问题确实是具体问题具体分析才行的。

该用户从未签到

发表于 2012-10-30 10:40:51 | 显示全部楼层
您觉得这么一大堆话和一个能说明问题的完整简单程序+资源,哪个更合适一些。。。

该用户从未签到

 楼主| 发表于 2012-10-30 11:12:57 | 显示全部楼层
array 发表于 2012-10-30 10:40
您觉得这么一大堆话和一个能说明问题的完整简单程序+资源,哪个更合适一些。。。

嗯,我确实想用程序表达,可是又不知道如何表达!程序太多了,那我就挑我认为这个问题最简单核心的代码吧!
天空盒以及海洋渲染部分:

        osgOcean::ShaderManager::instance().enableShaders(!disableShaders);
        m_pOceanSceneNode = new OceanSceneModel(sky_type,windDirection, windSpeed, depth, reflectionDamping, scale, isChoppy, choppyFactor, crestFoamHeight);
        m_pOceanSceneNode->getOceanScene()->setOceanSurfaceHeight(fOceanHeight);
        m_pOceanSceneNode->getOceanScene()->setNodeMask( m_pOceanSceneNode->getOceanScene()->getNormalSceneMask()
                                                                                                        | m_pOceanSceneNode->getOceanScene()->getReflectedSceneMask()
                                                                                                        | m_pOceanSceneNode->getOceanScene()->getRefractedSceneMask() );
        //初始化天空及天气类型
        m_pSkyDome = new SkyDome( 1900.f, 16, 16,sky_type);//osgocean里边的SkyDome函数
        m_pSkyDome->setNodeMask( m_pOceanSceneNode->getOceanScene()->getReflectedSceneMask() | m_pOceanSceneNode->getOceanScene()->getNormalSceneMask() );
        m_pOceanSceneNode->getScene()->setNodeMask(TRN_OCEAN);
        m_pOceanSceneNode->getScene()->setName("oceanF");
        m_pOceanSceneNode->getOceanScene()->addChild(m_pSkyDome);

        //设置相机属性
        m_pskyCamera->addChild(m_pOceanSceneNode->getScene());//m_pskyCamera是单独渲染天空盒与海洋的相机
        m_pskyCamera->setRenderOrder(osg::Camera:RE_RENDER);

        m_pRoot->addChild(m_pskyCamera);
天空盒代码:
        SkyDome::SkyDome( float radius, unsigned int longSteps, unsigned int latSteps,SKY_TYPE _skyType):_sceneType(SCENE_SUNNY)
{
        _cubemapDirs.push_back( "sky_SUNNY" );
        _cubemapDirs.push_back( "sky_MSUNNY" );
        _cubemapDirs.push_back( "sky_CLOUD" );
        _cubemapDirs.push_back( "sky_MCLOUD" );
        _cubemapDirs.push_back( "sky_FOGGY" );

        buildSky(radius,longSteps,latSteps,_skyType);
}

         void SkyDome::buildSky(float radius, unsigned int longSteps, unsigned int latSteps,SKY_TYPE _skyType)
{
        _sceneType = changeSceneType(_skyType);
        _cubemap = loadCubeMapTextures(_cubemapDirs[_sceneType]);
        compute( radius, longSteps, latSteps, 90.f, 180.f, 0.f, 360.f );
        setupStateSet(_cubemap);

}   

osg::ref_ptr<osg::TextureCubeMap> SkyDome::loadCubeMapTextures( const std::string& dir )
{
        enum {POS_X, NEG_X, POS_Y, NEG_Y, POS_Z, NEG_Z};

        std::string filenames[6];

        filenames[POS_X] = "../media/Ocean/textures/" + dir + "/east.png";
        filenames[NEG_X] = "../media/Ocean/textures/" + dir + "/west.png";
        filenames[POS_Z] = "../media/Ocean/textures/" + dir + "/north.png";
        filenames[NEG_Z] = "../media/Ocean/textures/" + dir + "/south.png";
        filenames[POS_Y] = "../media/Ocean/textures/" + dir + "/down.png";
        filenames[NEG_Y] = "../media/Ocean/textures/" + dir + "/up.png";

        osg::ref_ptr<osg::TextureCubeMap> cubeMap = new osg::TextureCubeMap;
        cubeMap->setInternalFormat(GL_RGBA);

        cubeMap->setFilter( osg::Texture::MIN_FILTER,    osg::Texture:INEAR_MIPMAP_LINEAR);
        cubeMap->setFilter( osg::Texture::MAG_FILTER,    osg::Texture::LINEAR);
        cubeMap->setWrap  ( osg::Texture::WRAP_S,        osg::Texture::CLAMP_TO_EDGE);
        cubeMap->setWrap  ( osg::Texture::WRAP_T,        osg::Texture::CLAMP_TO_EDGE);

        cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_X, osgDB::readImageFile( filenames[NEG_X] ) );
        cubeMap->setImage(osg::TextureCubeMap::POSITIVE_X, osgDB::readImageFile( filenames[POS_X] ) );
        cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Y, osgDB::readImageFile( filenames[NEG_Y] ) );
        cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Y, osgDB::readImageFile( filenames[POS_Y] ) );
        cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Z, osgDB::readImageFile( filenames[NEG_Z] ) );
        cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Z, osgDB::readImageFile( filenames[POS_Z] ) );

        return cubeMap;
}

void SkyDome::setupStateSet( osg::TextureCubeMap* cubemap )
{
    osg::StateSet* ss = new osg::StateSet;

    ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    ss->setTextureAttributeAndModes( 0, cubemap, osg::StateAttribute::ON );
    ss->setAttributeAndModes( createShader().get(), osg::StateAttribute::ON );
    ss->addUniform( new osg::Uniform("uEnvironmentMap", 0) );
    setStateSet(ss);
}

场景模型部分:
         m_pCourseNode = osgDB::readNodeFile("../course.ive");//包含了花草树木等大场景模型
         m_pRoot->addChild(m_pCourseNode);
主相机部分(main函数里边):
        osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer();  
        viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);

        //场景漫游器
        osg::ref_ptr<TravelManipulator> mainCamera =new TravelManipulator(physicsMgr,viewer);//这是一个相机操纵器,class TravelManipulator:public osgGA::MatrixManipulator  
        viewer->setCameraManipulator(mainCamera);
                viewer->getCamera()->setClearColor(osg::Vec4(0.0,0.0,0.0,0.5));
        viewer->getCamera()->setClearMask(GL_DEPTH_BUFFER_BIT);
                viewer->setSceneData( root );//root跟上边的m_pRoot是一样的,上边m_pRoot是root传递到另外一个类中的表示(说明一下,怕引起误会)


程序很大,别的内容太多,不知道还需要什么信息!实在不好意思!有需要后续可以补上一些可以说明问题的代码!谢谢array大哥!
不知道在解决树叶白边问题上,能不能从天空盒的代码上下功夫,修改天空盒的渲染参数什么的!之前试过setRenderBinDetails()没有什么用!

该用户从未签到

 楼主| 发表于 2012-10-30 11:28:16 | 显示全部楼层
qqqq.jpg ,这个是现在的渲染情况,不知道是什么原因!

该用户从未签到

 楼主| 发表于 2012-10-30 11:30:07 | 显示全部楼层
细框是白边,粗框是最新出现的黑边!

该用户从未签到

 楼主| 发表于 2012-11-2 11:39:36 | 显示全部楼层
黑边是因为关掉了树叶节点的混合,所以就成了黑边了!白边还是不知道,即便设置所有树叶子节点为TRANSPARENT_BIN,一样还是白边,如果关掉混合则是黑边,不知道是不是建模人员的问题,还是程序哪里出了问题?

该用户从未签到

发表于 2012-11-5 10:01:31 | 显示全部楼层
不排除是您的图片本身alpha通道没做好导致的

该用户从未签到

 楼主| 发表于 2012-11-5 13:34:33 | 显示全部楼层
array 发表于 2012-11-5 10:01
不排除是您的图片本身alpha通道没做好导致的

         贴图本身的alpha通道?可是有一个点:就是在max或者maya当中渲出来看的时候是没有什么问题的!然后导出osg或者ive模型以后,放到自己的osg程序中的时候就出现了这个白边的问题了!

     如果贴图的alpha通道没有做好的话,按理是不是在maya或者max里边渲的时候就会出现白边的问题呢?

该用户从未签到

发表于 2012-11-5 14:54:12 | 显示全部楼层
那就需要问写max和maya插件的人了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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