You're in a room without windows. Everything outside the room is culled. Frame rate is very high. Then you open the door and go outside into a large city. Some buildings have big windows showing the interior, so you can't cull the building interior. You're on a long street and can look off into the distance. Now keep the frame rate from dropping while not losing distant objects.
Games with fixed objects can design the world to avoid these situations. Few games have many windows you can look into. Long sightlines are often avoided in level design. If you don't have those options, you have to accept that distant objects will be displayed, and level of detail handling becomes more important than occlusion. Impostors. Lots of impostors.
Occlusion culling itself has a compute cost. I've seen the cost of culling big scenes exceed the cost of drawing the culled content.
This is one of those hard problems metaverses have, and which, despite the amount of money thrown at the problem, were not solved during the metaverse boom. Meta does not seem to have contributed much to graphics technology.
This is much of why Second Life is slow.
Start with a list of objects that were visible last frame. Assume they are visible this frame. Go ahead and draw them.
Then, for the list of things that were Not visible last frame, draw bounding box queries to build a conservative list of objects that might actually not be occluded this frame. This is expected to be a short list.
Take that short list and draw the probably-newly-visible objects.
Have queries attached to all of those draws so you end up with a conservative list of all of the actually-visible objects from this frame.
This obviously has problems with camera cuts. But, it works pretty well in general with no preprocessing. Just the assumption that the scene contents aren’t dramatically changing every frame at 60 FPS.
https://schedule.gdconf.com/session/optimizing-a-large-time-...
But see Roblox's own summary at: [1]
[1] https://devforum.roblox.com/t/occlusion-culling-now-live-in-...
I bet there is a special math term for "tilings that do/don't contains infinite lines", but I wasn't able to find it quickly. It's not the same as (a)periodic, since a periodic tiling could block the lines, and an aperiodic tiling could have one giant seam down the middle.
It was used extensively in outdoor games like Jak and Daxter.
[1] https://en.wikipedia.org/wiki/If_a_tree_falls_in_a_forest_an...
The BSP tree was also extremely useful for optimizing netcode for games like Quake 3 Arena and games within that family and time period I believe.
Also face normals (flat shading) are generally considered older tech than per-vertex lighting (Gouraud shading). Newer stuff since 2008-ish is generally per-pixel using normal maps for detail.
If I'm wrong please feel free to correct any of this, it's been about eight years since I last learned all of the different methods.
This worked very well but of course if the camera turned quickly, you would see pop-in. Not a modern technique, but an oldschool one.