It would seem that grooms only get one chance to be initialized for rendering, and if r.HairStrands.Enable is 0 during that initialization process, setting it to 1 later on does not allow the groom to be rendered.
I made the following changes to address the issue:
[Image Removed]
I am basically keeping a list of all GroomComponents “initialized” while r.HairStrands.Enable was false, then invalidate and recreate the associated resources when the cvar is true.
There is probably a more elegant way of doing that during the first initialization, where we would let the proper initialization go through, and just cut the rendering part if r.HairStrands.Enable is 0.
Or maybe a different cvar to use instead of r.HairStrands.Enable to disable hair rendering (performance reasons mainly) in certain scenarios, but still being able to turn then back on when we need to.
I have attached a demonstrating video done in vanilla 5.5.4.
Interesting! Wouldn’t be safer/simpler to just recreate the render data for all components? Something like that:
for (TObjectIterator<UGroomComponent> HairStrandsComponentIt; HairStrandsComponentIt; ++HairStrandsComponentIt) { if (HairStrandsComponentIt->IsRegistered()) { HairStrandsComponentIt->InvalidateAndRecreate(); } }If you don’t have much groom components, this is probably simpler.
Otherwise if you want to stick with your approach, you probably need to track when components get unregistered, to remove them from the array. Also maybe you need to change to a struct which is threadsafe (Not sure if all registering happen on the gamethread). You would also needs to clear the array once you have processed all the groom recreation, no?
Initially, I implemented recreating all components as you suggested, but decided to track only those needing recreation for performance optimization and to minimize potential stalling on the game thread during groom initializations.
I’m seeking a solution that allows rendering resources to be initialized fully when the component is streamed in, while deferring rendering until r.HairStrands.Enable (or any other cvar) is set to 1.
This approach aims to balance performance and flexibility without impacting the game thread significantly.
If there’s an alternative method or cvar that could facilitate this selective rendering control, I would greatly appreciate any insights.