zoukankan      html  css  js  c++  java
  • Ogre分层渲染

    转载请注明出处!http://www.cnblogs.com/pulas

    在超大的场景中,如果既想看到近处的物体,又想看到很远的物体,则必须把相机的远近裁剪面距离设得很大。远近裁剪面距离比例太大了,由于Depth Buffer的精度有限,这样就会导致Z-Fighting,挨在一起的物体表面会发生闪烁。

    解决这个问题有两种方法,一是用Logarithmic Depth Buffer,但是由于此方法需要对每个物体在shader中计算其对数深度,所以不太具有通用性,故没有深入研究。感兴趣的可以自己试试。

    相关参考资料:

    http://www.gamasutra.com/blogs/BranoKemen/20090812/2725/Logarithmic_Depth_Buffer.php

    http://www.gamedev.net/blog/73/entry-2006307-tip-of-the-day-logarithmic-zbuffer-artifacts-fix/

    第二种方法是使用分层渲染。首先设置一个比例合适的远近裁剪面距离,渲染很远处的物体,然后清除Depth Buffer,但是保留Color Buffer。然后再设置一个比例合适的远近裁剪面距离,渲染近处的物体。Madmarx写的一系列Ogre教程so3dtools中,其中A_1_FrustumSlicing例子很好的演示了怎么在Ogre中使用分层渲染。

    http://sourceforge.net/projects/so3dtools/

    http://www.ogre3d.org/forums/viewtopic.php?f=2&t=65275

    http://www.ogre3d.org/forums/viewtopic.php?f=2&t=46418

             

             bool COgreApplication::layeredRendering()

             {

                // This is the same, but it updates internal statistics
                // and get Listeners correctly called.
                m_pMainRenderWindow->_beginUpdate();
    
                Ogre::Real fFarClipDistance = m_pCamera->getFarClipDistance();
                Ogre::Real fNearClipDistance = m_pCamera->getNearClipDistance();
    
                // first render
                m_pSceneManager->setVisibilityMask(0x00000001);
    
                {
                    m_pCamera->setNearClipDistance(fFarClipDistance);
                    m_pCamera->setFarClipDistance(fFarClipDistance*1000);
                    m_pMainViewport->setOverlaysEnabled(false);
                    m_pMainViewport->setShadowsEnabled(false);
    
                    m_pMainRenderWindow->_updateViewport(m_pMainViewport);
    
                    // back to normal
                    m_pMainViewport->setOverlaysEnabled(true);
                    m_pMainViewport->setShadowsEnabled(true);
                }
    
                // second render
    // 第二遍渲染要渲染所有物体,以免处于两层交界处的物体发生异样
    m_pSceneManager->setVisibilityMask(0xFFFFFFFF); { m_pMainViewport->setClearEveryFrame(true, Ogre::FBT_DEPTH); m_pMainViewport->setSkiesEnabled(false); m_pCamera->setNearClipDistance(fNearClipDistance); m_pCamera->setFarClipDistance(fFarClipDistance); m_pMainRenderWindow->_updateViewport(m_pMainViewport); // go back to normal m_pMainViewport->setSkiesEnabled(true); m_pMainViewport->setClearEveryFrame(true, Ogre::FBT_COLOUR | Ogre::FBT_DEPTH); } // update all other viewports... m_pMainRenderWindow->_updateAutoUpdatedViewports(); m_pMainRenderWindow->_endUpdate(); // The drawn surface is then shown on the screen // (google "double buffering" if you want more details). // I always use vertical synchro. bool lVerticalSynchro = true; m_pMainRenderWindow->swapBuffers(lVerticalSynchro); return true; }

    调用方法:

                // I don't want it to be re-drawn when I do window->update() [2/22/2012 zhangzhonghui]
                m_pMainRenderWindow->setAutoUpdated(false);
    
    
                // I want to update myself the content of the window, not automatically. [2/22/2012 zhangzhonghui]
                m_pMainViewport->setAutoUpdated(false);
    
    
                // 分层渲染
                layeredRendering();
    
                // This update some internal counters and listeners.
                // Each render surface (window/rtt/mrt) that is 'auto-updated' has got its 'update' function called.
                m_pOgreRoot->renderOneFrame();
  • 相关阅读:
    利用delegate调试Ajax应用(转)
    Js悟透阅读节选(转)
    我的第一个PHP连接MSSQL2000示例。
    C# 时间相减得到天数
    修改桌面路径。其它路径。
    Player 网页歌曲播放器(CMP)
    麦咖啡 导出安全策略.reg文件。
    js实现几秒页面跳转的几种方式
    19,随机数,不重复。
    marquee 无缝循环
  • 原文地址:https://www.cnblogs.com/pulas/p/2866134.html
Copyright © 2011-2022 走看看