Frustum Prediction Culling
The snippet shows how to apply simple frustum culling to Quantum entities.
Culled entities in Quantum will not be updated when simulating predicted frames which is a performance improvement.
Read more about Profiling in Quantum.
Implementing a custom culling system involves three main steps:
Custom culling callback definition
Declare the callback that will be lately used for defining the actual culling logic:
C#
namespace Quantum
{
  using Photon.Deterministic;
  partial class FrameContextUser
  {
    public delegate bool CullingDelegate(FPVector3 position);
    public CullingDelegate CullingCallback;
  }
}
Custom culling System
Create a new system which triggers the callback.
P.S: this system should replace the regular culling systems which are provided by default on the SystemsConfig asset.
C#
namespace Quantum
{
  using UnityEngine.Scripting;
  using Quantum.Task;
  [Preserve]
  public unsafe class CustomCullingSystem : SystemBase
  {
    private TaskDelegateHandle _updateTask;
    public override void OnInit(Frame f)
    {
      f.Context.TaskContext.RegisterDelegate(Update, "CustomCullingSystem Update", ref _updateTask);
    }
    private void Update(FrameThreadSafe frame, int start, int count, void* arg)
    {
      var f = (Frame)frame;
      var context = f.Context;
      var filter = f.Filter<Transform3D>();
      while (filter.NextUnsafe(out var entity, out var transform))
      {
        if (context.CullingCallback(transform->Position))
        {
          f.Cull(entity);
        }
      }
    }
    protected override TaskHandle Schedule(Frame f, TaskHandle taskHandle)
    {
      if (f.IsVerified)
      {
        return taskHandle;
      }
      if (f.Context.CullingCallback != null)
      {
        var handle = f.Context.TaskContext.AddMainThreadTask(_updateTask, null);
        handle.AddDependency(taskHandle);
        return handle;
      }
      return taskHandle;
    }
  }
}
Frustum culling logic
Create a new script in which the culling logic is implemented and set in the callback previusly created:
C#
namespace Quantum
{
  using Photon.Deterministic;
  using UnityEngine;
  public class FrustumPredictionCulling : QuantumSceneViewComponent
  {
    public float ProximityRadiusOverhaul = 20;
    public override void OnActivate(Frame frame)
    {
      Game.Frames.Verified.Context.CullingCallback = Callback;
    }
    private bool Callback(FPVector3 position)
    {
      var unityPosition = position.ToUnityVector3();
      var distance = (unityPosition - Camera.main.transform.position).sqrMagnitude;
      if (distance < ProximityRadiusOverhaul * ProximityRadiusOverhaul) return false;
      var normalizedPos = Camera.main.WorldToViewportPoint(unityPosition);
      if (normalizedPos.z <= 0) return true;
      if (normalizedPos.y < 0 || normalizedPos.y > 1) return true;
      if (normalizedPos.x < 0 || normalizedPos.x > 1) return true;
      return false;
    }
  }
}