我尝试使用Ogre 1.8实现延迟着色。这是我最后的合成者:
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测试和灯光的边界体积。为此目的,我使用以这种方式设置的合成器监听器:
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,如上面的注释行所示。
但是,如果这些行被注释掉了,我改变了这样的合成器脚本:
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
}
}
}
}
DeferredShadingPostQuadLight
材料的片段程序每帧都会更新,没有任何问题。
我需要先向rt0
渲染,然后再渲染到target_output
。你能告诉我这里我做错了什么吗?谢谢!
答案 0 :(得分:0)
我终于搞清楚了! Ogre论坛上的答案经常会产生误导。我跟踪了pass_id
个变量 - 你提供给继承的虚函数notifyMaterialSetup
的变量,你放在这里的变量mat->getBestTechnique()->getPass(pass_id)
实际上是完全不同的值。我不知道为什么整个互联网上的例子都有这样的代码。这是完全错误的。 pass_id
指合成器通行证,pass_id
mat->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);
}
感谢您的关注!