Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul the cull mask internals for Lights, Decals, and Particle Colliders #102399

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

clayjohn
Copy link
Member

@clayjohn clayjohn commented Feb 4, 2025

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's layer_mask updated the pairing doesn't change.

This came from us using the PairInstances structure to handle the cull_mask. PairInstances is created as needed when updating an instance. Therefore, the cull_mask was only being used when updating the instance with the cull mask. Oops!

This PR does a few things:

  1. Moves the cull mask check into the pair/unpair functions (this has the same frequency as the check in PairInstances, which is ideal from a performance point of view)
  2. Expose particles_collision_get_cull_mask() to RendererSceneCull (this is needed so culling can actually happen)
  3. Changes the dependency notification for lights and decals to ensure that unpairing happens when the cull mask changes (this is necessary for number 1)
  4. Removes the decal culling inside the Mobile shader (this check is unnecessary and costs performance)

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:

  1. Instance pairing
  2. Instance dependencies
  3. cull_mask

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).

…liders

Properly pair and unpair instances based on cull mask to avoid any unnecessary processing and to ensure that changing the cull_mask and layer_mask actually updates culling behavior
@clayjohn clayjohn added this to the 4.5 milestone Feb 4, 2025
@clayjohn clayjohn requested a review from a team as a code owner February 4, 2025 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment