Skip to content

Stratkit Section Streaming

Summary

Divide objects into section in SubScene and streaming in and out using camera frustum

Entity Culling System

  • This system disables entities outside of camera frustum.
  • Other systems don't have to process these disabled entities.
  • Especially useful for some systems when a larger chunk of entities are outside of view, for example ZoomScaleSystem
    flowchart LR
        CullWorldEntityJob{CullWorldEntityJob}
        CullEntityJob{CullEntityJob}
        WillBeInvisibleTag -- enable --> Hide{Add Disabled}
        WillBeInvisibleTag -- disable --> Show{Remove Disabled}
        WorldRenderBounds --> CullWorldEntityJob
        CameraFrustum --> CullEntityJob
        CameraFrustum --> CullWorldEntityJob
    
        RenderBounds2 --> CullEntityJob
    
        CullEntityJob -- change --> WillBeInvisibleTag
        CullWorldEntityJob -- change --> WillBeInvisibleTag
    
        subgraph CullingSystem
            CullEntityJob
            CullWorldEntityJob
            WillBeInvisibleTag
        end
    
        subgraph CullingActivationSystem
            Hide
            Show
        end

For Systems Without Entity Creation

  • Should use UpdateAfter[typeof(CullingActivationSystemGroup)]
  • These systems will now only affect entities visible inside the camera frustum
    flowchart LR
        CullingSystem{Culling System} --> CullingActivationSystem{Culling Activation System}
        CullingActivationSystem --> ModuleSystem{Module Systems}
        style ModuleSystem fill:red
    flowchart LR
        Disabled -- present --> Excluded(Entities excluded from Queries)
        Disabled -- not present --> Included(Entities included in Queries)
        Included --> ModuleSystem{Module Systems}
        style ModuleSystem fill:red

For Systems With Entity Creation

  • Should use UpdateAfter[typeof(CullingSystemGroup)]
  • Should use UpdateBefore[typeof(CullingActivationSystemGroup)]
    flowchart LR
        CullingSystem{Culling System}
        CullingActivationSystem{Culling Activation System}
        ModuleSystem{Module Systems}
        CullingSystem --> ModuleSystem --> CullingActivationSystem
        style ModuleSystem fill:red
flowchart LR
    Disabled -- present --> Excluded(Armies Excluded From Queries)
    Disabled -- not present --> WillBeInvisibleTag
    WillBeInvisibleTag
    WillBeInvisibleTag -- enable --> OutOfView(Out of view Armies)
    WillBeInvisibleTag -- disable --> NewlyVisible(Newly visible Armies)
    NewlyVisible --> CreateUnit{Create Units}
    OutOfView --> DestroyUnit{Destroy Units}
    subgraph ModuleSystem[Module Systems]
        CreateUnit
        DestroyUnit
        CreateUnit --> ProcessUnit{Process Units}
    end
    style ModuleSystem fill:red

Section Streaming

Flow

flowchart LR
    ModuleSystem{Module Systems}
    SectionStreaming{Section Streaming System}
    MapGeneration{Map Generation}
    MapGeneration --> SubScenes --> SectionStreaming --> ModuleSystem
    style ModuleSystem fill:red

Map Generation

  • Run manually to add or modify maps
  • Run at Editor time
  • Produces SectionSubScenes for Section Streaming
    flowchart LR
        subgraph IObjectGenerator
            CityPropsGenerator
            PropsScatter
            RoadChunkGenerator
            SnappingPointsGenerator
        end
        subgraph ISectionObjectData
            ZoomPropData
            RoadObjectData
            SnappingPointData
        end
        CityPropsGenerator --> ZoomPropData
        PropsScatter --> ZoomPropData
        RoadChunkGenerator --> RoadObjectData
        SnappingPointsGenerator --> SnappingPointData
    
        subgraph SectionSubScene
            ZoomObjectAuthoring
            RoadRendererAuthor
            SnappingPointAuthor
        end
        ZoomPropData --> ZoomObjectAuthoring
        RoadObjectData --> RoadRendererAuthor
        SnappingPointData --> SnappingPointAuthor
    
        MapSectionDistributor{MapSectionDistributor}
        IObjectGenerator -- generate --> ISectionObjectData
        ISectionObjectData -- collect --> MapSectionDistributor
        ISectionObjectData -- has --> Position
        ISectionObjectData -- has --> LOD
        Position --> MapSectionDistributor
        LOD --> MapSectionDistributor
        MapSectionDistributor -- group into --> SectionSubScene

Map Section Distributor

flowchart LR
    subgraph SectionSubScene
        direction LR
        ZoomObjectAuthoring
        RoadRendererAuthor
        SnappingPointAuthor
    end
    SectionSubScene --> Bakers --> Entity
    subgraph Entity
        Position --> SceneSection
        LOD --> SceneSection
        SceneSection
    end
    subgraph EntityScene
        Section0["Section 0: auto load"]
        Section1
        Section2
    end
    SceneSection -- section = 1 --> Section1
    SceneSection -- section = 2 --> Section2

    Section1 -- union of all objects --> SceneBoundingVolume1
    Section2 -- union of all objects --> SceneBoundingVolume2

Map Section Culling

flowchart LR
    subgraph SubScene
        Section0["Section 0: auto load"]
        Section1
        Section2
    end

    Section1 -- has --> SceneBoundingVolume
    Section2 -- has --> SceneBoundingVolume
    Section1 -- has --> SectionLOD
    Section2 -- has --> SectionLOD

    MapSectionCullingSystem{MapSectionCullingSystem}
    SceneBoundingVolume --> MapSectionCullingSystem
    SectionLOD --> MapSectionCullingSystem
    CameraFrustum --> MapSectionCullingSystem
    MapSectionCullingSystem --> LoadSection{Load Section}
    MapSectionCullingSystem --> UnloadSection{Unload Section}

Culling vs Streaming

Culling Streaming
Scope Entire Map Visible Sections
Assessibility Culled entities are still accessible Unloaded entities are not accessible
Connectivity No restriction on linking to other entities Restricted to linking to entities of the same section
Memory Culled entities still consume memory Unloaded entities do not occupy memory
Suitable For Gameplay that requires global info Decorations or localised gameplay elements

Infinite Scrolling

Infinite Scrolling

Army

flowchart TB
    EntityCullingSystem --> ArmyTransformUpdateSystem --> TransformSystem
    ArmyTransformUpdateSystem --> LocalTransform
    TransformSystem --> LocalToWorld
    LocalTransform --> LocalToWorld
    LocalToWorld --> EntityGraphics
    TransformSystem --> RenderBoundsUpdateSystem
    RenderBoundsUpdateSystem --> EntityGraphics
    LocalToWorld --> RenderBoundsUpdateSystem
    LocalToWorld --> WorldRenderBound
    RenderBoundsUpdateSystem --> WorldRenderBound
    WorldRenderBound --> EntityGraphics
    WorldRenderBound --> EntityCullingSystem
    EntityCullingSystem --> CoordinateShifting --> LocalTransform

Component Based Culling

AComponentBasedCullingSystem is an abstract base class for systems that manage visibility transitions for entities based on a specific component type. It handles enabling and disabling visibility state tags and is designed to work with extended functionality, such as managing IsInvisibleTag.

  • Features:

    • Handles entities transitioning between visible and invisible states.
    • Enables or disables the IsInvisibleTag for entities transitioning out of or back into visibility using SetComponentEnabled (this is not default behavior; by default, only WillBeInvisibleTag is used).
    • Provides flexibility for derived systems to implement additional visibility-related operations.
  • Warning:

    • Struct Components: If the target component (TTargetComponent) is a struct implementing IComponentData, you should rely only on the WillBeInvisibleTag for visibility state management. This avoids unnecessary complexity and ensures optimal performance.
    • Class Components: This system is primarily designed for scenarios where TTargetComponent is a class (IComponentData reference type) and cannot be a struct. Using a class-based component should be a fallback for cases where struct-based solutions are not feasible.
    • Refer to the package documentation in the readme for additional usage guidelines.
  • Usage:

    • Extend AComponentBasedCullingSystem<TTargetComponent> and implement:
      • OnBecomeInvisible(EntityQuery query): Custom behavior for entities transitioning to an invisible state.
      • OnBecomeVisible(EntityQuery query): Custom behavior for entities transitioning to a visible state.
  • Example Systems:

    • MapBehaviourCullingSystem: Handles toggling the enabled state of BehaviourRef.
    • MapObjectCullingActivationSystem: Handles toggling the active state of GameObjectRef.
    • VisibilityChangeToProcessSystem: Enables the VisibilityChangeToProcess component to track visibility transitions for further processing by other systems.
  • Integration:

    • Automatically integrates into the CullingSystemGroup pipeline.
    • Leverages RequireForUpdate with combined queries, ensuring efficient processing.
    • Provides flexibility to customize visibility logic while maintaining consistent behavior for culling systems.

flowchart LR
    WillBeInvisibleTag -- enable --> EnableIsInvisibleTag{Enable IsInvisibleTag}
    WillBeInvisibleTag -- disable --> DisableIsInvisibleTag{Disable IsInvisibleTag}

    EnableIsInvisibleTag --> VisibilityStateTransition{Handle Visibility State Transition}
    DisableIsInvisibleTag --> VisibilityStateTransition

    VisibilityStateTransition --> DerivedSystems{Derived Systems}

    subgraph DerivedSystems
        MapBehaviourCullingSystem
        MapObjectCullingActivationSystem
        VisibilityChangeToProcessSystem
    end
- Additional Notes on VisibilityChangeToProcessSystem: - VisibilityChangeToProcessSystem is a separate system built on top of AComponentBasedCullingSystem. - It ensures the VisibilityChangeToProcess component is enabled for entities during visibility transitions. - This allows further systems to explicitly track and process visibility changes beyond the frame in which they occur. - The VisibilityChangeToProcess component remains active until explicitly disabled by a later system, providing flexibility for deferred processing.