BindToRenderStepped is laggy vs RenderStepped connection directly

My code has this in it:

game:GetService("RunService"):BindToRenderStep("CubeGui3D", Enum.RenderPriority.Camera.Value-1, function(dt)
--game:GetService("RunService").RenderStepped:Connect(function(dt)

And by moving the -- to the line above it, the performance is drastically increased.
I also tried changing the priority to 1 and 0, which did not make it any better.

According to the wiki,

The BindToRenderStep function binds a custom function to be called at a specific time during the render step. There are three main arguments for BindToRenderStep: name, priority, and what function to call.

As it is linked to the client’s rendering process, BindToRenderStep can only be called on the client.

Additionally,

All rendering updates will wait until the code in the render step finishes. Make sure that any code called by BindToRenderStep runs quickly and efficiently. If code in BindToRenderStep takes too long, then the game visuals will be choppy.

So then I tested to see if longer code makes the game visuals choppy on the direct connection.
I added this bad boy:

--game:GetService("RunService"):BindToRenderStep("CubeGui3D", Enum.RenderPriority.Camera.Value-1, function(dt)
game:GetService("RunService").RenderStepped:Connect(function(dt)
	for i=1,4000000 do
		i = i*2 + i*3
	end

Very laggy, ~18 FPS for both methods.
For .RenderStepped
image
For BindToRenderStepped
image
The load for RenderStepped:
image
The load for BindToRenderStepped:
image
The very consuming for loop took a lot of render performance away, dropping FPS drastically.

Next I did a framerate check to see if it was skipping frames. Both sat at about 60 FPS average when measured.

So my question is this: “Inefficient” code made no difference with a large load, and frames are not being skipped, so how is it that the rendering looks incredibly choppy with BindToRenderStepped?

In another test, I tried .Stepped and .Heartbeat;
These actually yielded similar results as BindToRenderStepped.

3 Likes

After much testing and thought I figured out what was happening.
I was doing

game:GetService("RunService"):BindToRenderStep("CubeGui3D", Enum.RenderPriority.Camera.Value-1, function(dt)

which was causing the function to use the previous CFrame of the camera and then it would update the camera’s CFrame after I updated the part’s CFrame.
This would cause the part to be one update behind where it is supposed to be. It looked very bad and not smooth.
RenderStepped on the other hand would be fired very last which meant it used camera’s updated CFrame.

The solution was to do this:

game:GetService("RunService"):BindToRenderStep("CubeGui3D", Enum.RenderPriority.Camera.Value+1, function(dt)

Which meant the function would be called after the camera finished its update.

It changed from
Enum.RenderPriority.Camera.Value-1
to
Enum.RenderPriority.Camera.Value+1

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.