1

我正在尝试使用 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。你能告诉我我在这里做错了什么吗?谢谢!

4

1 回答 1

0

我终于明白了!食人魔论坛上的答案常常具有误导性。我追踪了pass_id变量——你提供给继承的虚函数的变量notifyMaterialSetup和你放在这里的变量mat->getBestTechnique()->getPass(pass_id)实际上是完全不同的值。我不知道为什么互联网上的示例都有这样写的代码。这是完全错误的。pass_id指的是合成器通道,而pass_idofmat->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);
}

感谢您的关注!

于 2012-12-24T07:46:53.287 回答