Note: The early versions are not optimized for usage in a full game.
Side note: When recording, I drop my FPS. When not recording, it’s a steady 60 FPS.
My system has a few important features that his did not:
- It has priority rendering. This means that not all objects are created equal.
This is very important, because it allows us to save on performance. For example, player characters are always rendered (even when hidden) and updated at the max FPS (Heartbeat). This is to ensure that players move smoothly, and never jitter out of existence. However, the Baseplate (if there is one) is updated at 10 FPS. The Baseplate almost never moves, whereas the player constantly does, so we can get away with checking the player movement more than the Baseplate.
See how my character is smoother than the falling boxes?
- It updates, not recreates.
A naive implementation would clear all children of the ViewportFrame and then redo it every frame. Mine creates the Object, and leaves it in there (unless it moves out of the Camera’s view) and updates the CFrame or Transparency when it needs to be, rather than every frame. Because I check for changes, I can also set the FPS of the object (How often I check). This allows the priority rendering.
Also, in addition to the objects, it doesn’t also set the Camera CFrame every frame. It uses the :GetPropertyChangedSignal(“CFrame”) to update the Camera only when needed.
- Supports Transparency
Mine allows parts to be counted as visible if they are behind objects with Transparency above 0.1. Under 0.1 Isn’t enough to see well, so it’s not worth rendering. Gotta save where you can
At 0.1, you can see that the crate and barracks aren’t there, but only if you look hard enough.
At 0.7, it knows to render through it and adds them in (and they’ll be updated at 20FPS)
- Model rendering
If any part within a model is visible, I render the whole model. This is actually faster than rendering only the visible parts, because I only have to check the first couple parts of a model before deciding to render. Fewer raycasts!
I’ve decided to open source my code (and I tried to comment it clearly) (sorry for the mess) so that we can learn from each other! Please critique, give suggestions, and report bugs!
CameraViewPortV2.rbxl (249.9 KB)
The wonderful @sircfenner has pointed out to me that because the combination of raycasting, screen projection, and GetDescendants takes so much power, checking for visibility is actually slower! Relying on the ViewportFrame to decide what to render would be faster!
However, one cannot simply just keep cloning the entire workspace! Thus I proudy present… a new version!
This version still has this feature:
A naive implementation would clear all children of the ViewportFrame and then redo it every frame. Mine creates the Object, and leaves it in there and updates the Properties when it needs to be, rather than every frame.
Now, why is this one so special?
It doesn’t lower your FPS! Instead, it lowers its own FPS, updating less but keeping your game smooth!
However, it will still update players at max FPS, even if the rest is slowed down. Priorities!
Here’s an example:
Note how the game is a perfect 60FPS (Even while recording!), and the player in the ViewportFrame is 60FPS, but the rest is slowed down a little.
There is instructions commented in the code on how to switch to update everything (not just players) at Max FPS. All you have to do is comment/uncomment the lines as instructed.
Here’s the file!
CameraViewPortV3.rbxl (160.9 KB)
Edit: New version!
I polished up and optimized this rendering technique for a Dual Render scope system. (Super cool, go check it out!) Once I did that, I turned the polished version into a security camera system again!
This is running at 60 FPS with a giant, detailed map:
Here’s the file:
Security Camera System.rbxl (1.1 MB)