#bug? DisableRendering component causing chunk fragmentation

1 messages · Page 1 of 1 (latest)

bronze gust
#

Doing this over and over in a system:

for (var i = 0; i < Size * Size; i++) {
    var shouldBeShown = i < _index || i >= _index + _range * 2;
    var isShown = !SystemAPI.HasComponent<DisableRendering>(_entities[i]);

    if (shouldBeShown == isShown) continue;

    if (shouldBeShown) {
        state.EntityManager.RemoveComponent<DisableRendering>(_entities[i]);
    } else {
        state.EntityManager.AddComponent<DisableRendering>(_entities[i]);
    }
}
_index += _range;

Causes the chunks to fragment by a lot. The lower the range variable is, the more they fragment. I've tested both with AddComponent/RemoveComponent, EntityCommandBuffer (one at a time), and AddComponent/RemoveComponent with an array of all entities that should change that frame, and all have the same result.

Is there a good way of doing structural changes that prevents fragmentation?

#

Actually, might just be DisableRendering specifically? I tried making a different component and it seems to be fine. So might be a bug in how graphics is implementing enable/disable rendering.

I'm on entities 1.3.14 and entities-graphics 1.3.2

olive ore
#

Wasn't there an enablable you can use to disable rendering? Why not just use that instead?

limpid crest
#

yeah public struct MaterialMeshInfo : IComponentData, IEnableableComponent can do

bronze gust
#

bug? DisableRendering component causing chunk fragmentation

prime wraith
#

so this problem is entirely due to chunk components

#

adding DisableRendering causes the chunk component EntitiesGraphicsChunkInfo to be removed

#

i'm not sure why, but it's what happens

#

and adding/removing chunk components is what causes fragmentation

#

EntityManager.RemoveChunkComponentData<EntitiesGraphicsChunkInfo>(m_DisabledRenderingQuery);

#
            m_DisabledRenderingQuery = GetEntityQuery(new EntityQueryDesc
            {
                All = new[]
                {
                    ComponentType.ChunkComponentReadOnly<EntitiesGraphicsChunkInfo>(),
                    ComponentType.ReadOnly<DisableRendering>(),
                },
            });```
#

basically chunk components are what causes fragmentation in entities

#

once you remove the chunk component, then when you remove DisableRendering, it no longer has the chunk component so no longer matches other rendering entities which have the chunk component, there won't be moved into the existing chunks, instead it'll be in its own chunk, then it needs to have the chunk component added back by rendering which just does it to the existing chunk

#

[Rendering, ChunkComponent] - normal rendering entities

AddComponent DisableRendering
[Rendering, DisableRendering, ChunkComponent]

Unity then removes ChunkComponent leaving us with
[Rendering, DisableRendering]

RemoveComponent DisableRendering leaves us with
[Rendering]
As it doesn't have ChunkComponent it won't be moved into the [Rendering, ChunkComponent] archetype group so now we have 2 chunks

[Rendering, ChunkComponent] and [Rendering]

Rendering system then adds ChunkComponent back to Rendering archetype
[Rendering, ChunkComponent]
But it's now a separate chunk so we have 2 chunks with same archetype
[Rendering, ChunkComponent] and [Rendering, ChunkComponent]

#

i'd personally try to remove this line of code
EntityManager.RemoveChunkComponentData<EntitiesGraphicsChunkInfo>(m_DisabledRenderingQuery);

#

and see if it breaks or not

#

if it doesn't, it'll fix your issue

fair stirrup
#

disabling rendering is the old way, using materialmeshinfoni is the new way
you don’t have to add or remove extra components for that, which makes it better in the long term too
i fail to see how disabling rendering is better than using an existing component

fair stirrup
prime wraith
#

yes

fair stirrup
#

how come lol

prime wraith
#

there's overhead to checking enable components

#

its
you have X entities that render
vs
you have X entities that can render, check enable component on all them to see if they should render

#

now the enable component is very convenient for toggling rendering

#

and should definitely be used

#

but if you know something is going to be disabled for seconds, or minutes etc

#

using disablerendering makes sense

prime wraith
prime wraith
fair stirrup
#

so adding or removing components, which can cause structural changes, is a better choice for the long term?

prime wraith
#

short term pain, long term gain

#

personally i don't really use disablerendering component because if i'm going to disable something for so long, i completely unload the assets

#

but it's totally valid

bronze gust
#

they're not deduplicated at least

prime wraith
#

to avoid chunk component fragmentation i personally add chunk components to all Prefab and Disabled entities

#

so thatn when i instantiate them i don't cause fragmentation

#

otherwise everytime you instantiate an entity, add a chunk component, it fragments

bronze gust
#

Hmm, seems like commenting out that line makes the tag not disable rendering at all

#

lol, just noticed this earlier in the file. So seems like they're aware of it being an issue for other stuff at least

#

nvm, I'm stupid, I accidentally renamed the temp tag component I made to disable rendering when mass replacing LOL

#

but does seem like commenting it out makes it so DisableRendering doesn't work and doesn't disable rendering

#

I also tried adding back the chunk component before removing DisableRendering, to see if it would assign it to an existing chunk if it had the correct arcetype, but doesn't seem like that worked.

prime wraith
#

it basically relies on moving the chunk component to stop rendering atm

#

i think if you went through and everywhere MaterialMeshInfo was used as a WithAll (and state isn't ignored) and added a WithNone(DisablingRendering) it'd probably work

#

but now we're getting into an actual fork situation rather than just a minor change

bronze gust
#

Hmm, doing this before adding/removing DisableRendering:

        var entities = SystemAPI.QueryBuilder().WithAll<EntitiesGraphicsChunkInfo>().Build().ToEntityArray(Allocator.Temp);
        for (var i = 0; i < entities.Length; i++)
        {
            state.EntityManager.RemoveChunkComponent<EntitiesGraphicsChunkInfo>(entities[i]);
        }

also doesn't fix the issue. But in theory shouldn't that have been a laggy solution since they'd all get into the same non-chunk-componented chunk before getting added the same chunk component to

prime wraith
#

it won't move it to an existing chunk

#

unless you're enabling and disabling all the entities in the same frame

#

the enable will still fragment unless they were all enabled at same time

bronze gust
#

removing all instances of EntitiesGraphicsChunkInfo would in theory be the same as enabling and disabling all of them in the same frame

prime wraith
#

oh i missread your code

#

i just assumed you were doing that for a targetted amount of entities

#

but no what you did probably just made it worse

#

you removed it per entity

#

so you probably made every entity its own chunk

#

ah hmm no maybe not, it probably should merge

bronze gust
#

no, strangely enough it had no effect on the chunk count

#

thought the reason might be that ChunkWorldRenderBounds also prevented it from merging with an existing chunk, but removing that too also doesn't make it merge

#

using query inside RemoveChunkComponentData instead of individual entities also had no difference

#

^ testing with inverting my hide/show code and hiding most entities

#

Since ChunkWorldRendererBounds is removed from every frame, in theory they should be merging chunks then. Unless the RenderFilterSettings or RenderMeshArray is somehow fragmenting them

#

hmm, no, both have the same value. Only difference are the WorldRenderBounds

prime wraith
#

another chunk component

#

oh wait no

#

thats ChunkWorldRenderBounds

#

you mean the normal one

#

tbh chunk components cause all sorts of issues like this, you really need to manually defrag or use enable components

bronze gust
#

Is there a way to manually defrag?

#

Since it's not like with managed shared components where you can just set the reference and it'll work

bronze gust
#

Since adding DisableRendering should make it so they're not in the same chunk even without the chunk component removed

#

I guess the docs don't specify what's happening when an entity with a chunk component changes chunk

#

nvm, it was just hidden on a different page

prime wraith
#

at least my best guess

#

i forgot how heavy entities graphics goes on chunk components

#

any structural change on presentation entities can lead to this chunk fragmentation

#

depending how it's done

bronze gust
#

I guess I could use ChunkWorldRenderBounds and only add / remove DisableRenderer to whole chunks at a time

#

Though I guess at that point the built in culling probably would be good enough, however that works. Unless it doesn't do any cpu side culling

#

Oh well, worry for another time, gotta get some sleep. Maybe a unity engineer will see this and knows a good solution, lol

prime wraith
#

just use enable component

#

are you actually running into a situation where performance is that bad?

#

if you're disabling whole chunk anyway then it goes the fast path and there's not a whole lot of difference

bronze gust
#

True. I was thinking of using it for some of my logic tied to rendering too, but I can just use my own component for that, then set MeshFilter to enabled/disabled per chunk based on that component instead. And tbh, probably should also just test with the enableable component to see if it's actually slow or not lol

simple fossil
#

What version are you on ? I had that issue a long time ago, that if you baked this tag or added it a spawn time it would create 1 chunk per entity spawned, but this was fixed a while back (I think ? ido'nt have this issue anymore at least) , and I still used DisableRendering extensively without chunk shenanigans during runtime

#

And I use ECB to disable them one by one

bronze gust
bronze gust
bronze gust
#

ig I could log it

fair stirrup
bronze gust
bronze gust
prime wraith
#

What's your disable fragmentation like

bronze gust
#

top two are just the world, so those can be ignored