Protfolio-Emanuel-Polsky / Assets / _Project / Code / Culling / CullingSystem.cs
CullingSystem.cs
Raw
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Rendering;

namespace GarmentButton.Culling
{
    public partial struct CullingSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<EndSimulationEntityCommandBufferSystem.Singleton>();
            state.RequireForUpdate<CameraFrustumPlanes>();
            state.RequireForUpdate<VisibleTag>();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var ecbSingleton = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
                .CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter();

            var cameraFrustumPlanes = SystemAPI.GetSingleton<CameraFrustumPlanes>();
            state.Dependency = new CullJob()
            {
                Planes = cameraFrustumPlanes,
                Ecb = ecbSingleton
            }.ScheduleParallel(state.Dependency);
        }
    }

    [BurstCompile]
    [WithAll(typeof(VisibleTag))]
    [WithOptions(EntityQueryOptions.IgnoreComponentEnabledState)]
    public partial struct CullJob : IJobEntity
    {
        public CameraFrustumPlanes Planes;
        public EntityCommandBuffer.ParallelWriter Ecb;

        [BurstCompile]
        private void Execute([EntityIndexInQuery] int sortKey, Entity e, in WorldRenderBounds wrb)
        {
            var aabb = wrb.Value; // Unity.Mathematics.AABB (Center, Extents)
            bool visible = AabbInsideFrustum(aabb.Center, aabb.Extents);
            Ecb.SetComponentEnabled<VisibleTag>(sortKey, e, visible);
        }

        [BurstCompile]
        private bool AabbInsideFrustum(float3 center, float3 extents)
        {
            return AabbInsidePlane(center, extents, Planes.P0)
                   && AabbInsidePlane(center, extents, Planes.P1)
                   && AabbInsidePlane(center, extents, Planes.P2)
                   && AabbInsidePlane(center, extents, Planes.P3)
                   && AabbInsidePlane(center, extents, Planes.P4)
                   && AabbInsidePlane(center, extents, Planes.P5);
        }
        //

        [BurstCompile]
        private bool AabbInsidePlane(float3 c, float3 e, float4 plane)
        {
            float3 n = plane.xyz;
            float d = plane.w;

            // Project extents onto plane normal (abs(n) dot extents)
            float r = math.dot(math.abs(n), e);
            float s = math.dot(n, c) + d;

            // Outside if s + r < 0
            return (s + r) >= 0f;
        }
    }
}