2012-12-21 14 views
1

我试图使用Ogre 1.8实现延迟着色。这是我最后的合成:Ogre3d /通过合成器侦听器和通过标识符访问传递

compositor DeferredShadingShowLit 
{ 
    technique 
    { 
     texture rt0 target_width target_height PF_A8R8G8B8 
     texture_ref mrt_output DeferredShadingGBuffer mrt_output 

     target rt0 
     { 
      input none 
      shadows off 

      pass clear 
      { 
       identifier 1 
      } 

      pass render_quad 
      { 
       identifier 2 
       material DeferredShadingPostQuadLight 
       input 0 mrt_output 0 
       input 1 mrt_output 1 
      } 
     } 

     target_output 
     { 
      input none 

      pass render_quad 
      { 
       identifier 3 
       material DeferredShadingFinal 
       input 0 rt0 
      } 
     } 
    } 
} 

我需要通过灯光位置,即每帧改变到DeferredShadingPostQuadLight材料(用于渲染灯)。它是一个简单的例子,我还没有实现任何优化,例如z测试和灯光边界卷。对于被设置这种方式,目的IM使用合成听者:

class LightListener : public Ogre::CompositorInstance::Listener 
{ 
    public: 

     LightListener(Ogre::Vector3 alightPos); 
     virtual ~LightListener(); 
     virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); 
     virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); 

     Ogre::Vector3 lightPos; 
     Ogre::GpuProgramParametersSharedPtr fpParams; 
}; 

LightListener::LightListener(Ogre::Vector3 alightPos) 
{ 
    lightPos = alightPos; 
} 

LightListener::~LightListener() 
{ 
} 

void LightListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    //if (pass_id == 2) // This gives me error 
    fpParams = mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters(); 
} 

void LightListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    //if (pass_id == 2) // This gives me error 
    fpParams->setNamedConstant("lightPos", lightPos); 
} 

问题是我可以通过ID不能访问通行证如上面的注释行。

但是,如果线被注释和我改变合成脚本这样的:DeferredShadingPostQuadLight材料

compositor DeferredShadingShowLit 
{ 
    technique 
    { 
     texture rt0 target_width target_height PF_A8R8G8B8 
     texture_ref mrt_output DeferredShadingGBuffer mrt_output 

     target_output 
     { 
      input none 
      shadows off 

      pass clear 
      { 
      } 

      pass render_quad 
      { 
       material DeferredShadingPostQuadLight 
       input 0 mrt_output 0 
       input 1 mrt_output 1 
      } 
     } 
    } 
} 

片段程序得到更新每一帧没有任何问题。

事情是我需要渲染到rt0首先,然后才target_output。你能告诉我在这里做错了什么吗?谢谢!

+0

我想你可能在[官方论坛]上有更好的答案(http://www.ogre3d.org/forums/)。 – Synxis

回答

0

我终于明白了! Ogre论坛上的答案往往是误导性的。我追踪了pass_id变量 - 您提供给继承的虚拟函数notifyMaterialSetup的变量和您在此放置的变量mat->getBestTechnique()->getPass(pass_id)实际上是完全不同的值。我不知道为什么互联网上的例子都有这样写的代码。这是完全错误的。 pass_id是指排料合格,而pass_idmat->getBestTechnique()->getPass(pass_id)是指材料合格。我有我自己的例子,只需改变代码就可以了:

void LightListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    if (pass_id == 2) 
    fpParams = mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); 
    // I put 0 here because my material has only one pass 
} 

void LightListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    if (pass_id == 2) 
    fpParams->setNamedConstant("lightPos", lightPos); 
} 

感谢您的关注!