[Ogre 2.3] Light masks

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


CbbK
Gnoblar
Posts: 14
Joined: Sun Nov 22, 2020 3:29 pm
x 1

[Ogre 2.3] Light masks

Post by CbbK »

Hi. I'm trying to manage 2 scenes at the same time, each with their own lights.
One is rendered on the whole screen, while another is rendered to a texture, drawn on the UI. In practise it's the outside view, and inside view of the cargobay of the vehicle. This part works fine.
Now to avoid outside lights from lighting inside (it has no windows) and vice versa I used setVisibilityFlags and setLightMask with 0x1 for the outside scene, and 0x2 for the inside, I set this flags on objets and lights. Both scenes are in separate render queues, outside is on default render queue ID, inside is on ID 51.
The 2 passes on the compositor are :
Outside :
pass render_scene
{
visibility_mask 0x1
light_visibility_mask 0x1
overlays off
rq_first 0
rq_last 11
}

Inside :
pass render_scene
{
visibility_mask 0x2
light_visibility_mask 0x2
overlays off
rq_first 51
rq_last 52
}

Items are correctly masked and drawn by the correct passes, but all are lit by all lights. Disabling forward clustered didn't change anything.
If I understood this post viewtopic.php?t=92405 correctly I don't need fine granularity because my objects are drawn in separate passes already. So what can I do, what I am missing, to make sure all objects are lit by the correct lights please?

Thanks

CbbK
Gnoblar
Posts: 14
Joined: Sun Nov 22, 2020 3:29 pm
x 1

Re: [Ogre 2.3] Light masks

Post by CbbK »

After digging into this it seems that lights are not culled separately but once per frame, saved into Ogre::SceneManager::mGlobalLightList.
Ogre::Hlms and Ogre::HlmsPbs don't take the viewport's light visibility mask into account so it seems normal that all objects are lit by all lights, they are all sent to the shaders.

To fit with my needs, I changed how numLightsPerType is filled in Ogre::Hlms, only counting lights when the mask fits.

Code: Select all

Ogre::uint32 lightMask = cameras.renderingCamera->getLastViewport()->getLightVisibilityMask();
...
if( lightType == Light::LT_DIRECTIONAL && ((*itor)->getLightMask() & lightMask))
    ++numLightsPerType[Light::LT_DIRECTIONAL];

In Ogre::HlmsPbs I do the same check, skipping lights that don't fit the mask :

Code: Select all

Ogre::uint32 lightMask = cameras.renderingCamera->getLastViewport()->getLightVisibilityMask();
//Skip inactive lights (e.g. no directional lights are available
//and there's a shadow map that only accepts dir lights)
while( !lights[shadowLightIdx].light || [b]!(lights[shadowLightIdx].light->getLightMask() & lightMask)[/b])
    ++shadowLightIdx;

This works! I only did that for directional lights in my case as I don't understand the rest of the code enough. @dark_sylinc What do you think about it? Thank you.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5533
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1391

Re: [Ogre 2.3] Light masks

Post by dark_sylinc »

Your first change appears to be correct.

However regarding your 2nd change, CompositorShadowNode::buildClosestLightList should already be accounting for light visibility masks, which means your last change to Ogre::HlmsPbs here:

Code: Select all

Ogre::uint32 lightMask = cameras.renderingCamera->getLastViewport()->getLightVisibilityMask();
//Skip inactive lights (e.g. no directional lights are available
//and there's a shadow map that only accepts dir lights)
while( !lights[shadowLightIdx].light || [b]!(lights[shadowLightIdx].light->getLightMask() & lightMask)[/b])
    ++shadowLightIdx;

Shouldn't be necessary (and might introduce bugs?). If shadow-mapping lights ignore the light mask, then it's possible OgreNext didn't detect the shadow node had to be recalculated.

You can force it by doing this in your compositor script:

Code: Select all

pass render_scene
{
shadow_node myShadowNode recalculate 
}

Maybe CompositorShadowNode::buildClosestLightList should also be accounting SceneManager::getLightMask()?

CbbK
Gnoblar
Posts: 14
Joined: Sun Nov 22, 2020 3:29 pm
x 1

Re: [Ogre 2.3] Light masks

Post by CbbK »

Thank you, indeed the 2nd modification wasn't necessary as the lights are already filtered in CompositorShadowNode::buildClosestLightList.
This method uses the visibilityFlags and not lightVisiblityFlags, I'll simplify my modifications and use only the 1st flag.