Part:BeingDrawn()

I am currently trying to find ways to have the least amount of parts within the workspace at any given point in time. This is so I can have a persistance with smaller objects I create through the course of play, but don’t actually need them to exist at the current point in time.

  • Shotgun shells
  • Ragdolls
  • Exploded barrels
  • Spaghetti noodles I dropped on the floor

My method of doing this is by creating a bounding box and calling it a ViewCube, everything within the room’s dimensions belongs to that ViewCube, and is pre-set as belonging to it. If I add objects I can check quickly if it exists within the space of a ViewCube. This should allow me to save all the little bits and bobs a player leaves through a level without getting taxing by calculating things that won’t be seen anyway.

However, I only have access to WorldToScreenPoint to see if it is within the bounds of the screen, this doesn’t tell me if what I’m looking at is actually being drawn.

In order for the view cube to now work, I take the Vector3 of all of its normal faces and check it with this method WTSP. To see if any of those points are actually in view I would need to ray, but if I look at this object at an angle which doesn’t show any of those points, despite being on screen, it will be refered to as not on screen.
I can up the amount of points each ViewCube has, but for a large level that starts to get out of hand per frame.

The aim is to only de-parent and re-parent things that are absolutley needed for a particular area, without doing this action an absurd amount of times.

Here is an example of what I’m attempting to achieve;

Running without FE so I can have a server/client view.

As you can see from the clip, there is an issue where even when I can’t see a room, its still considered OnScreen, and when I still can see a room its no longer OnScreen.

There are a ton of gameplay uses for this as well, from stopping enemies attacking you while you aren’t looking at them to spawning them where you can’t see them, to trigger events.

I’ve been looking at making an interaction module for my game, where one of the interactions would be looking at something and an action happening, it would be rigged like this.

  • Have two parts
    –The object we are looking at
    –The object we need to see it through
  • Use WorldToScreenPoint to find if they are within N amount of pixels to eachother
  • Use the Z property returned to us to make sure we are looking through them in the correct order
  • Cast rays <-- Holy moly, if I have lots of sight interactions in my game, this could get costly at certain angles

If I instead could just check if they are both being drawn, it’d be a lot easier, especially if that information already exists!

9 Likes

Sounds like a good idea! However, I don’t think Part:BeingDrawn() is quite the right name. It would more likely be Part.IsVisible or something of the like.

There’s an interesting performance side effect to note when doing occlusion culling, and I ran into this issue when I was trying to do this for The Stalker: Reborn’s lobby.

When you load/unload groups of parts in Roblox, you may have noticed that there is a framerate dip that comes with doing so. Now imagine having this framerate dip everytime that you hide and show a room that you can’t see. It only gets more expensive when there are more parts in a room.

You ultimately run into a trade off where you have to decide whether it’s better to do occlusion culling in a room, or to just keep everything there and optimize your geometry. Usually you should just go with the latter. You have a lot of memory to work with, the individual effects you’re mentioning aren’t really taxing at all, unless you’re trying to do something crazy expensive on each frame. In fact you’re probably taxing your performance more by trying to cull the rooms, than whatever cost the rooms have in the first place.

9 Likes

That said, I have found that distance culling is absolutely worth it in games like Ultimate Driving. It can be enabled in the game’s options and helps a lot on mid/lower-end hardware.

2 Likes

But doesn’t Roblox cull far-away stuff at lower graphics levels already?

Supposedly yes, but the results say it’s not aggressive enough to keep high framerate in Westover et al. on the hardware I used.

In general, detecting if an object is visible on the screen is an expensive operation. Roblox at least does camera frustum culling, meaning stuff outside of your camera frustum doesn’t render. They could use more complicated heuristics to get more accurate occlusion culling, but more accurate heuristics are more expensive and after a certain level of accuracy, performance gains would be negated.

Roblox, and almost every 3D videogame, uses z buffers to draw things in the proper order, but a zbuffer isn’t something you can efficiently query to tell if a specific part is visible.

1 Like

I may be wrong but imagine Roblox will do a better job of culling parts than a user can do in Lua?

Good luck though.

1 Like