New property: PVInstance.Visible

As a Roblox developer, it is currently frustrating, difficult, and badly performing to “unrender” PVInstances (Models and BaseParts). In order to create systems for LOD, or temporary object cleanup, developers must either unnecessarily delete the PVInstance, iterate over all of its descendants and explicitly set LocalTransparencyModifier (also recording their original values and hoping nothing else touches it in the meantime), or move the object very far from the camera. All of these methods come at a significant cost in terms of performance.

In my game, Aftermath, I very frequently move models and base parts in bulk to a very far away location to prevent rendering them from unnecessary distances. I use a similar system for zombies which aren’t within a reasonable distance. And I use this technique for building interiors that don’t need to be rendered 95% of the time. This is a common technique employed by many games, since reparenting objects tends to be far more expensive, and destroying objects often invokes a large cleanup job (I would often see upwards of 60ms), and LocalTransparencyModifier is too unreliable and slow in large models.

In cases where collisions aren’t a concern, and all we need to do is make it so a PVInstance is not rendered it would be ideal to do this quickly and efficiently. This idea has been proposed many times in the past, but having a property such as Visible is commonly used in the engine, and it behaves exactly the same as I’d expect it to in this case every where else its being used.

Just speculating, but it seems as though something like this already exists in the engine with the new culling system, so a similar property being exposed to developers would be awesome.

11 Likes

How would this work for LOD? Don’t you care about disabling collision also in that case so you don’t have multiple pieces of collision geometry stacked on top of eachother?

Also, moving the objects to a distant location is not as bad a solution as you make it out to be.

The Roblox engine is designed around a physics simulation, where moving objects is designed to be a fast-path, as simulated objects will be moving every frame. Taking advantage of that fast-path for swapping things out is actually just a reasonable use case.

In the case of LOD, I don’t ever need collisions for my other LOD levels, or at least that’s a sacrifice I’m willing to make, although I’m sure the engine itself could do a far better job of handling LOD for us. Having control over visibility just seems like a simpler solution that we’re more likely to get, and has other uses as well.

I don’t mean that moving objects is a bad solution, it’s really the only solution we have. But moving objects, especially if those objects involve a humanoid, has always been a bottleneck for me.

Take my use-case on building interiors for example, if I want to move an interior to, say, 0, 10e8, 0 and I use streaming in my game, I have to move the interiors into the camera on the server (so I can validate bullet collisions and other server-sided simulations), recreate the interiors on the client and move them around as needed. If I don’t do this, then the objects will be streamed out and incur a large deferred delete job.

Moving an interior takes roughly 0.15-0.2ms on my PC (which isn’t a slow computer) since there are a lot of objects involved in that move. Presumably I could improve this performance by welding everything together (just a hunch, I haven’t tested this). The collisions are not at all a bottleneck for me, render time is, so moving them really isn’t necessary, and incurs a lot of extra work for the client and far more complex validation for bullets on the server side. I would also imagine it causes a lot of updates in the physics BVH or KD-tree, whatever it is that’s used internally.

Another good example I can think of in my game are my ground items. I have thousands of items scattered around the map, they’re not rendered on the server, but the information used in generating the models is streamed to the client using the built in streaming. These items never have any collisions at all, and some of them have a very good amount of detail… which we could reduce, sure. But if I could just not render these at all until players are within their desired visibility radius for them then that seems like a great option to me. Currently, I “cache” these models to the extent that I am able to and I move them far away and that works, but it begs the question in my mind “why can’t I just not render these?”

I certainly don’t mean to dog on moving objects at all as a solution. You definitely know more about the internals than I do, but given my use-case here does it not make sense to just be able to flick a switch and it doesn’t render at all anymore? Perhaps the LOD use-case isn’t a great one, I was trying to make this more broadly applicable. Most games don’t need to go to the trouble that my game needs to in order to run well on the client. Perhaps all of this could be solved with more granular streaming capabilities though. In any case, seems like a great capability for the engine to support in my mind.

Are you moving it as just a bunch of anchored parts in a Model?

If you weld it together into an assembly with only the root part being anchored that will fully take advantage of simulation and make it much faster to move.

1 Like