Ogre3d / получает доступ через слушатель композитора и идентификаторы прохода

Я пытаюсь реализовать отложенное затенение с помощью 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);
}

Проблема в том, что я не могу получить доступ по их идентификатору, как показано в комментариях выше.

Однако, если строки закомментированы, и я изменяю скрипт композитора следующим образом:

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, Не могли бы вы показать мне, что я делаю здесь не так? Спасибо!

1

Решение

Я наконец понял это! Ответы на форумах огров часто вводили в заблуждение. Я проследил 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);
}

Спасибо за внимание!

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]