Overhaul the cull mask internals for Lights, Decals, and Particle Colliders #102399
+67
−14
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
While discussing #101947 I thought I found an easy fix for the cull_mask for particle colliders. However, once I started implementing the fix, I realized that it suffered from the same problems as #73706 and #78253 i.e. the pairing of instances only works when the object with
cull_mask
is updated. When the Geometry has it'slayer_mask
updated the pairing doesn't change.This came from us using the
PairInstances
structure to handle thecull_mask
.PairInstances
is created as needed when updating an instance. Therefore, thecull_mask
was only being used when updating the instance with the cull mask. Oops!This PR does a few things:
PairInstances
, which is ideal from a performance point of view)particles_collision_get_cull_mask()
to RendererSceneCull (this is needed so culling can actually happen)I'm targeting 4.5 with this change since it is a fairly big change and is riskier than is justifiable for this late beta stage
Fixes: #61014
Fixes: #73706
Fixes: #78253
Background
This PR engages a few concepts that don't get a lot of attention:
Instance pairing
Pairing is the process of creating a connection between two instances. This allows them to keep track of each other and to notify each other of important information. For example, if a mesh is animated, it can set all the lights touching it to dirty so they know to recalculate shadows. This caching system is very helpful for performance as you can avoid updating information unnecessarily and only update what has changed. Every instance maintains a list of items it is paired with.
We use instance pairing for the
cull_mask
so we can avoid doing extra processing per frame of items that will ultimately fail the cull test. We don't cull lights or decals when using the Forward+ backend because all lights and decals need to be rendered to the cluster buffer. In that case culling has to happen in the shader.Instance dependencies
These should be notified whenever an instance-derived object changes something that will impact its dependencies. I.e. if a mesh or material need to know what is happening to a MeshInstance, or if a GeometryInstance needs to know what happens with a light.
Each notification type is handles separately. In this case, we want the notification that clears the currently paired instances as the cull_mask change requires us to pair from scratch. We can't just attempt to pair again since we will have a stale pair.
cull_mask
This mask is used by certain instances that interact with others to do their thing. For example, cameras, lights, decals, reflection probes, particle colliders, all have to interact with other instances to do their job. The cull_mask allows those nodes to choose not to interact with a particular visual layer.
Particle colliders use the cull_mask as well, because ultimately they are culling a GeometryInstance which has a visual layer. #93291 implemented physics collision layers and a physics mask for particles, but this required breaking compatibility, and ultimately may lead to confusion since particle colliders can't interact with any physics primitives, they are a visual effect and can only impact particles (which are also not physics primitives).