The engine PR playcanvas/engine#9195 adds RenderComponent#shadowCascadeMask (2.22), which lets an entity choose which directional shadow cascades it casts into. This was requested in playcanvas/engine#9126, where the reporter measured a solid usability and performance win from keeping large or distant meshes out of the near cascades, and it currently needs a script walking the mesh instances. It would be good to expose it in the render component inspector.
The field
components.render.shadowCascadeMask, type number, default 255 (pc.SHADOW_CASCADE_ALL)
- bit flags are
pc.SHADOW_CASCADE_0 (1), pc.SHADOW_CASCADE_1 (2), pc.SHADOW_CASCADE_2 (4), pc.SHADOW_CASCADE_3 (8)
- only effective when Cast Shadows is enabled, and only for directional lights
- existing scenes have no such key, and the engine defaults to all cascades, so no migration is needed
Suggested UI
A row of four checkboxes labelled 0-3, sitting under Cast Shadows in the Render component.
Having looked at how this would fit, the cleanest route is a small custom PCUI element registered as a new attribute type, the same way the Layers, Batch Group and colour fields already are. It would hold four boolean inputs and expose a single number, so it needs value get/set to compose and decompose the bits, plus the values setter for the multi-entity "various" state - the existing colour input is the closest template for that pattern. After that it is one entry in the render component's attribute list and one tooltip/reference entry.
Worth also adding the new type to the set of field types the right-click copy/paste menu supports, so it behaves like Layers does.
Nothing should be needed on the viewport side: the value is a plain number, the viewport already assigns component properties generically, and component data is passed verbatim to addComponent.
One thing worth avoiding: implementing it as four separate alias-backed boolean fields, in the style of how Custom AABB drives its two sub-fields. Each checkbox would then have to hand-write its own undo/redo handling, and alias-backed fields miss out on template override highlighting since that is registered per path.
A cheaper alternative, if a new element feels like too much: reuse the Layers-style multi-select dropdown with Cascade 0-3 as the options, converting the selected array to and from the mask. Less code, but a less direct UI than checkboxes.
Caveats worth knowing
numCascades lives on the light component, so the render inspector cannot know how many cascades actually exist. Showing all four and letting the tooltip explain that surplus bits are ignored is probably the pragmatic option.
- Because the value is a single number, two people toggling different bits at the same time is last-write-wins rather than a merge. An array-valued field would merge, but the engine API is a mask.
- Changing the mask at runtime on a batched entity will not re-split the batch group until it is rebuilt. This is the same existing behaviour as Cast Shadows.
- The runtime lightmapper bakes with a single cascade, so a mask that excludes cascade 0 also excludes that mesh from baked directional shadows.
The engine PR playcanvas/engine#9195 adds
RenderComponent#shadowCascadeMask(2.22), which lets an entity choose which directional shadow cascades it casts into. This was requested in playcanvas/engine#9126, where the reporter measured a solid usability and performance win from keeping large or distant meshes out of the near cascades, and it currently needs a script walking the mesh instances. It would be good to expose it in the render component inspector.The field
components.render.shadowCascadeMask, type number, default255(pc.SHADOW_CASCADE_ALL)pc.SHADOW_CASCADE_0(1),pc.SHADOW_CASCADE_1(2),pc.SHADOW_CASCADE_2(4),pc.SHADOW_CASCADE_3(8)Suggested UI
A row of four checkboxes labelled 0-3, sitting under Cast Shadows in the Render component.
Having looked at how this would fit, the cleanest route is a small custom PCUI element registered as a new attribute type, the same way the Layers, Batch Group and colour fields already are. It would hold four boolean inputs and expose a single number, so it needs
valueget/set to compose and decompose the bits, plus thevaluessetter for the multi-entity "various" state - the existing colour input is the closest template for that pattern. After that it is one entry in the render component's attribute list and one tooltip/reference entry.Worth also adding the new type to the set of field types the right-click copy/paste menu supports, so it behaves like Layers does.
Nothing should be needed on the viewport side: the value is a plain number, the viewport already assigns component properties generically, and component data is passed verbatim to
addComponent.One thing worth avoiding: implementing it as four separate alias-backed boolean fields, in the style of how Custom AABB drives its two sub-fields. Each checkbox would then have to hand-write its own undo/redo handling, and alias-backed fields miss out on template override highlighting since that is registered per path.
A cheaper alternative, if a new element feels like too much: reuse the Layers-style multi-select dropdown with Cascade 0-3 as the options, converting the selected array to and from the mask. Less code, but a less direct UI than checkboxes.
Caveats worth knowing
numCascadeslives on the light component, so the render inspector cannot know how many cascades actually exist. Showing all four and letting the tooltip explain that surplus bits are ignored is probably the pragmatic option.