Camera stutters while interpolating at high velocities

I’m trying to interpolate the camera to follow a target part, which works great at low speeds(for the most part), but trying to follow anything going at a decent speed causes the part to appear as if it’s stuttering.

Here’s some examples:

Camera following player at 16 WalkSpeed https://i.gyazo.com/fd42b530457c77ab0ca10c4050116904.gif
Camera following player at 100 WalkSpeed https://i.gyazo.com/05ed543685913de8892ab52d99935b87.gif
Camera following kart at 100 SPS https://i.gyazo.com/e597ca585553b301871e3e32c7d7e166.gif

Here’s the code:

local camera = workspace.CurrentCamera
local head = game.Players.LocalPlayer.Character:WaitForChild(“Head”)

game:GetService(“RunService”).RenderStepped:connect(function()
camera.CameraType = Enum.CameraType.Scriptable
camera:Interpolate(head.CFrame*CFrame.new(0,2.5,10),head.CFrame,.05)
end)

I’ve tried interpolating at lower speeds, but no matter what I still get stutter. I know the part isn’t actually stuttering though because when I use RenderStepped and set the camera’s CFrame to the head’s CFrame it looks fine:

Camera stuck to head with RenderStepped https://i.gyazo.com/c9ab756d276be5bfda9dfe9e4c8b70cd.gif

Any ideas on how I could go about interpolating the camera without stutter? I’ve tried using a part with a BodyGyro & BodyPosition, but that has the stutter issue as well. Also, some players have complained about how the part would lag too far behind on their computer, which means it wouldn’t be optimal for lower-end pcs, which is why I want to use :Interpolate().

4 Likes

You need to do two things.

  • Use head:GetRenderCFrame instead of head.CFrame.

  • Use cf:lerp(cf, a) to interpolate instead of Camera:Interpolate since you’re doing it on a render step.

headCF = head:GetRenderCFrame()
camera.CFrame = camera.CFrame:lerp(CFrame.new(headCF * Vector3.new(0, 2.5, 10), headCF.p), 0.05)
3 Likes

Ooh, never knew :GetRenderCFrame existed! Much appreciated :wink:

Oop, looks like another problem has risen. I tried the new code out on a character first and it looked fine at 16 WalkSpeed, so I applied it to the kart. Turns out it still stutters at high speeds, and since the kart has the ability drive upside-down, I can’t use CFrame(pos1,pos2) because the camera will flip.

CFrame(pos1,pos2) https://i.gyazo.com/54dbcd4f4d44c5e7a3cc35ed262aabb6.gif

I made modifications to allow proper rotation:

local chassisCF = chassis:GetRenderCFrame()*CFrame.new(0,7.5,10)
camera.CFrame = camera.CFrame:lerp(chassisCF,.2)

Though I still get this stutter (GIF framerate dampens the stutter a bit):

New CFrame https://i.gyazo.com/246fc2977a814596a476da5b9caec26c.gif
Edit: No, it's not because the surface has indents
New CFrame[2] https://i.gyazo.com/f31469a0226ca6546a4cb91a1c1e15d4.gif
Edit: Tried using BindToRenderStep and setting it to a higher priority, doesn't seem to help any.

Try printing the car’s Velocity.magnitude while driving, see if that stutters too.
(Then we know whether the car actually stutters, or if it’s a render issue)

Did you try it without lerping? (you never know)

As you can see here, even at a constant velocity of 100, there is still stutter. I should re-iterate that everything but the thing that the camera follows seems to be smooth.

Example GIF https://i.gyazo.com/8e97213de346d372459abf0b3b3aba33.gif

I’ve tried lerping, interpolating, bindtorenderstep, rendercframe, all different kinds of combos, all with no prevail. @Quenty seems to have written an article on this very issue(if not, then a very similar one), explaining how it could be linked to “how ROBLOX is handling parts, and networking, or something….”.

Kinda skimmed through the article, but it seems the problem might be network ownership? Have you tried using SetNetworkOwner and setting the client as the owner of all the car parts?

Of course I am, otherwise the karts would be near un-controllable due to latency. Every part of the kart has NetworkOwnership set to the player. The kart is also parented to the character.

At this point I’d recommend using damped springs. Here’s Here’s a link that provides an implementation in C# that can be easily ported to Lua:

www.ryanjuckett.com/programming/damped-springs/

His “link” pointed to http://www.ryanjuckett.com/programming/damped-springs/.

Thanks, looks like I’ve got some reading to do :huh:, I’ll let you guys know how this works out if it does.

I’ve gone and translated it to Lua, though now I have absolutely no idea how to apply it. I’ve messed around with it a bit, but I don’t understand how to apply it to a Position/CFrame.

Anyone care to take a look and shed some light?

Pastebin: http://pastebin.com/xxVJjMbK

I’d much rather use :Interpolate() or :lerp() as they’d probably be a lot more efficient, but they both seem to have the stutter issue.

I also have a Damping module that I use for smooth camera stuff. I use this in Angels Fifteen to make it feel like your camera is swaying around with the movement of the plane. It’s open-source within my Team Crazy Game Framework:

https://github.com/Sleitnick/TeamCrazyGameFramework/blob/master/src/game/StarterPlayer/StarterPlayerScripts/Main.Damping.module.lua

2 Likes

This is excellent! Though, I integrated it into my game and I still seem to get the stutter effect. I’m certain the kart itself isn’t stuttering because when I simply lock the camera to the chassis with an offset nothing stutters. It makes no sense that the kart appears jittery while everything else looks fine and smooth. Any idea why this might be happening?

Try using BindToRenderStep with the Camera priority

I’ve been using First priority, switched to Camera priority and still the same effect. I’m wondering if the stutter is so subtle in first-person that I just don’t notice it or something, but I don’t think that’s the case and I don’t think it has to do with the velocity of the kart since it stutters even while at a constant speed.

Edit: I should also say that the default camera doesn’t show any stuttering either

Edit: I made a repro file(StutterRepro.rbxl) with the roblox jeep to show that it’s not because of my code. The camera script is located in the PlayerGui.

This isn’t meant to be a bump, but I want to make sure this doesn’t go off the radar. This is a huge issue that could make or break my game(and potentially many others in the future), and it would be devastating to have to either cancel the game(very unlikely) after building up a following for the project on both roblox and social media(not to mention the hundreds of hours I’ve poured into it), or to release the game with a horribly jittery camera that hurts the players eyes. I’ve been looking into this issue as much as possible, but I still can’t find anything related to this besides old, abandoned treads from as far back as 2013. Just want to make sure this is at least being looked into. I’ll let this sit for a while before I post again, but this is something that I really need to figure out. :angst:

I’m pretty sure this is an issue with the vehicle bouncing and not anything with the camera. When I printed out the Y value of the chassis’s CFrame * the offset constant, I got this:

17.520645141602
17.48729133606
17.501874923706
17.488796234131
17.498933792114
17.501306533813
17.478925704956
17.501398086548
17.486587524414
17.543092727661
17.572566986084
17.545532226563
17.474153518677
17.516923904419
17.512046813965
17.502639770508
17.513778686523
17.504692077637

When I removed the lerping and just set the camera directly to chassisCF, I experienced the same bouncing, so this is definitely a problem with vehicles bouncing on flat terrain and not camera jittering. Physics stuff is @Khanovich’s favorite IIRC.

In my case the kart never physically touches the ground unless going up a steep surface, so I’ve even wondered if it’s not related to how the camera interacts with bodymovers. I’ve read in a few different threads that the update time between bodymovers and the camera are different, resulting in a stutter, but I’m not 100% this is the case. I update the bodymovers and camera on BindToRenderStep at the same priority, so I’m not sure what’s happening, it definitely happens with any physics-based objects I’ve tried it on though. Maybe @Khanovich could shed some light.

Is the Vehicle being drive Server Owned, or Locally Owned by the driving Client?