質問

Im trying to implement deferred shading using Ogre 1.8. This is my final compositor:

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
            }
        }
    }
}

I need to pass the lights position, that is altered every frame to the DeferredShadingPostQuadLight material (used to render lights). Its a simple example and i havent implemented any optimizations such as z tests and bounding volumes for lights. For that purpose im using compositor listener that is set up this way:

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);
}

The problem is i cant access passes by their id as shown in the commented lines above.

However, if the lines are commented out and i change compositor script like this:

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
            }
        }
    }
}

fragment program of the DeferredShadingPostQuadLight material gets updated every frame without any problems.

Thing is i need to render to rt0 first and only then to target_output. Can you please show me what im doing wrong here? Thank you!

役に立ちましたか?

解決

I finally got it figured out! Answers on Ogre forums were often misleading. I traced the pass_id variables - the one you supply to the inherited virtual function notifyMaterialSetup and the one you put here mat->getBestTechnique()->getPass(pass_id) are actually completely different values. I have no idea why examples all over the internet have this code written like this. This is completely wrong. pass_id refers to compositor passes, whereas pass_id of mat->getBestTechnique()->getPass(pass_id) refers to materials passes. I got my own example working simply by altering the code like this:

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);
}

Thanks for your attention!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top