Search Unity

[HybridRenderer] Spawning identical entities from code in different frames creates separate chunks

Discussion in 'Graphics for ECS' started by Nothke, Mar 1, 2020.

  1. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    Workaround found! See here

    Problem is explained in the title..

    Why doesn't spawning in different frames add to the same chunk?

    Spawning 100 entities at once:

    upload_2020-3-1_21-51-44.png

    Spawning one entity per frame:

    problemee.gif

    Test Code:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Mathematics;
    3. using Unity.Entities;
    4. using Unity.Transforms;
    5. using Unity.Rendering;
    6.  
    7. public class RenderEntityTest : MonoBehaviour
    8. {
    9.     EntityManager manager;
    10.     EntityArchetype particleArch;
    11.  
    12.     public Mesh mesh;
    13.     public Material material;
    14.  
    15.     RenderMesh rm;
    16.     RenderBounds rb;
    17.  
    18.     void Start()
    19.     {
    20.         manager = World.DefaultGameObjectInjectionWorld.EntityManager;
    21.  
    22.         particleArch = manager.CreateArchetype(
    23.             typeof(Translation),
    24.             typeof(LocalToWorld),
    25.             typeof(RenderBounds),
    26.  
    27.             typeof(RenderMesh));
    28.  
    29.         rm = new RenderMesh()
    30.         {
    31.             castShadows = UnityEngine.Rendering.ShadowCastingMode.On,
    32.             receiveShadows = true,
    33.             mesh = mesh,
    34.             material = material,
    35.         };
    36.  
    37.         rb = new RenderBounds() { Value = mesh.bounds.ToAABB() };
    38.  
    39.         // This will create 100 entities in the same chunk:
    40.         //SpawnABunch(100);
    41.     }
    42.  
    43.     void Update()
    44.     {
    45.         // This will create a new chunk for each new entity:
    46.         SpawnABunch(1);
    47.     }
    48.  
    49.     void SpawnABunch(int count)
    50.     {
    51.         for (int i = 0; i < count; i++)
    52.         {
    53.             Spawn(UnityEngine.Random.insideUnitSphere * 10);
    54.         }
    55.     }
    56.  
    57.     void Spawn(Vector3 pos)
    58.     {
    59.         Entity e = manager.CreateEntity(particleArch);
    60.         manager.SetComponentData(e, new Translation { Value = pos });
    61.         manager.SetSharedComponentData(e, rm);
    62.         manager.SetComponentData(e, rb);
    63.     }
    64. }
    65.  
     
    Last edited: Mar 1, 2020
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I've seen this issue pop up multiple times on these forums. Could you test something for me out of interest?

    Instead of including RenderMesh as part of the archetype, do a AddSharedComponentData<RenderMesh>
     
  3. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    Nope, it behaves the same.

    I am pretty sure this is a problem with the AddWorldAndChunkRenderBounds system, because if you don't add one of the necessary components, for example MeshBounds, which prevents that system from kicking in, the entities are added into existing chunks as they should be.
     
  4. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    @tertle I took a peek into AddWorldAndChunkRenderBounds, and copied over components it adds to my archetype and now it works.

    Code (CSharp):
    1.  
    2. archetype = manager.CreateArchetype(
    3.    typeof(Translation),
    4.    typeof(LocalToWorld),
    5.    typeof(RenderBounds),
    6.    typeof(RenderMesh),
    7.  
    8.    // copied from AddWorldAndChunkRenderBounds system:
    9.    ComponentType.ReadWrite<WorldRenderBounds>(),
    10.    ComponentType.ChunkComponent<ChunkWorldRenderBounds>()
    11.    );
    12.  
    Although I found a solution, this looks like a big problem that should not happen and Unity must fix
     
  5. TLRMatthew

    TLRMatthew

    Joined:
    Apr 10, 2019
    Posts:
    65
    What version of Hybrid Renderer package are you running?

    The latest version is supposed to have resolved this chunk fragmentation problem, according to this post.
     
  6. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    I'm using the latest 0.3.4-preview.24 in Unity 2019.3.3f1

    And yes, I need to create RenderBounds manually as is mentioned in the post. So, apparently this version should've had the fragmentation issue fixed, but it doesn't?
     
  7. TLRMatthew

    TLRMatthew

    Joined:
    Apr 10, 2019
    Posts:
    65
    That's my understanding, but perhaps he means that the change has been made to enable a future fix.
    @SebastianAaltonen ?
     
  8. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    If you use prefabs, the issue is solved. If you don't use prefabs and instead build entity from scratch, then you need to add a couple of chunk components manually to solve the issue. I believe you need at least to add ChunkWorldRenderBounds. You could check in entity debugger which chunk components exist in the entity and add those yourself.

    Also it's worth noting that adding all components manually causes several structural changes, and is thus significantly slower than instantiating a prefab which has all components added beforehand during conversion. Prefabs are the fast path for instantiation and result in zero fragmentation too.
     
    TLRMatthew likes this.
  9. SebastianAaltonen

    SebastianAaltonen

    Unity Technologies

    Joined:
    Feb 21, 2020
    Posts:
    112
    We will add a test scene to hybrid.renderer sample projects to show how to build entity from scratch in code in a way that doesn't cause fragmentation. I would however still recommend instantiating prefabs as that is faster.