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

私はついにそれを理解しました!Ogreフォーラムでの回答は、誤解を招くことがよくありました。変数をトレースし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 に答える