#Problems with lerping and fps
1 messages · Page 1 of 1 (latest)
ive tried a lot and searched a lot and found nothing
the main thing here is that the lerping is exaggerated on lower fps
i shouldve expected it honestly
Problems with lerping and fps
!code
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
anyways this is a case of wrong lerp
Applying lerp so that it produces smooth, imperfect movement towards a target value.
that's your issue
you're also lerping a rotation instead of slerping it
thanks ill trythis
forgot smh
You are not really doing a LERP… The time part of the LERP is set as deltaTime*20f… Which, if the framerate is consistent is going to keep giving you the same value (approximately).
So you would probably be better off using Vector3.RotateTowards with appropriate max values
still tryna figure out how lerp works its so hard to wrap my head around stuff
you're kinda using lerp "wrong", as in it's not actually a lerp
see the wronglerp link above
the "correct" use of lerp, as a linear interpolation, is in the form y = lerp(a, b, t), where a and b do not change
mhm i noticed thanks
using UnityEngine;
public static class ExponentialScript
{
public static Vector3 VectorLerp(ref Vector3 value, Vector3 target, float decay, float delta) => Vector3.Lerp(value, target, 1 - Mathf.Exp(-decay * delta));
public static Quaternion QuatSlerp(ref Quaternion value, Quaternion target, float decay, float delta) => Quaternion.Slerp(value, target, 1 - Mathf.Exp(-decay * delta));
}
i did this just now actually to try and get it to work
and then here for example
desiredRotation = ExponentialScript.VectorLerp(ref desiredRotation, clampAngles, 10f, Time.deltaTime);
you shouldn't call these lerp/slerp, they just aren't that
the L in lerp/slerp stands for linear, which you seem to not be going for
idk what to call them :(
there's a ton of ways to describe smoothing
you could say it's smoothtowards or whatever
ill just keep it as "lerp" since i assigned it to many stuff already
dont wanna go renaming all of them
the other thing is also
i have a spring system
using UnityEngine;
public static class SpringSystem
{
public static Vector3 Update(Vector3 pos, ref Vector3 velocity, Vector3 target, float delta, float freq = 3f, float damp = .3f)
{
if (delta <= 0) return pos;
float angle = 2 * Mathf.PI * freq;
Vector3 dir = pos - target;
Vector3 acc = -angle * angle * dir - 2 * damp * angle * velocity;
velocity = velocity + acc * delta;
pos = pos + velocity * delta;
return pos;
}
}
and i doubt this is frame independent
ides have rename functionality
you can right click > rename symbol or use F2
it'll update the references too
pretty sure this is using deltaTime fine already
its still weird when enabling lag
modifying velocity by acceleration in a unit time, and modifying position by velocity in a unit time
not sure what im supposed to be looking at here
is this Update called once per frame?
yes
the position is a tiny bit more exaggerated
position recoil i mean
and also
the mouse movement
i dont have it applied
if the mouse movement on its own seems to be framerate dependant, the issue with recoil might be related to that
hold on how do i
A tool for sharing your source code with the world!
thats the whole sway update thingy
its called in update
those are for the arms though
A tool for sharing your source code with the world!
this is for the gun itself
Just noting again that LERP requires a ‘t’… which goes from 0 to 1… deltaTime will not work. That is just the time since the last frame, so if you are calculating this every update, then it is irrelevant.
You should remove LERP altogether and use rotateTowards…
or you need to save the result including the start time of the update and apply LERP to those values… until it has reached t =1 (which is however you want to track time and have the calculation run)
the above pattern was wronglerp, a different usage of lerp that kinda works
I don't think this is a big issue for you, but it may be of interest: a frame-rate independent lerp, e.g. damp. You can use this one with delta-time and it will give consistent results.
https://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
(it's not a lerp then lol)
public static float Damp(float a, float b, float lambda, float dt)
{
return Mathf.Lerp(a, b, 1 - Mathf.Exp(-lambda * dt))
}
I beg to differ
it isn't a lerp
by definition, it isn't a lerp
the L stands for linear. this isn't linear
it's not that deep
Sure. We can argue about semantics and definitions, but that doesnt help anyone here
i'd argue separating the concepts helps a lot
and heres the spring script
bump
its still really exaggerated on low fps...,.,
i guess you have it in a regular update loop, you need to make it independent from variable deltatime
this is something you would put in the fixed update and then interpolate in the regular update
or you can do some kind of fixed timestep logic yourself
isnt fixed update for physics
it's for everything that requires a fixed update
im so close to giving up
which
your entire spring system update
integration like this gives very different results with different delta times
if you want to understand this, you can see it if you write out the numbers of a few frames with different delta times
especially when your inputs steer you in different directions
i put the spring updates in fixedupdate
it didnt do anything
https://en.wikipedia.org/wiki/Explicit_and_implicit_methods
there's a tiny graph here on this page that shows how various integration methods are off from the "truth" (which is what you are doing with advancing acceleration, velocity and position)
Explicit and implicit methods are approaches used in numerical analysis for obtaining numerical approximations to the solutions of time-dependent ordinary and partial differential equations, as is required in computer simulations of physical processes. Explicit methods calculate the state of a system at a later time from the state of the system ...
well, if it's in the fixed update and you input it Time.fixedDeltaTime, it should at least give consistent results regardless of framerate (unless you have some other inputs that depend on framerate)
so you can tweak it to behave as you want
im not this smart man
the point is to see that there is an error compared to the ground truth for any movement that is split up into timesteps
the bigger the timestep, the bigger the error
so variable timestep means variable error, which results in behaviour that can change with framerate
oh man this is gonna take a while isnt it
im not a master coder i dont have a clue what youre talking about
if (lag)
{
if (Time.time > timer)
{
timer = Time.time + .01f;
System.Threading.Thread.Sleep(90);
}
}
right
its a debug thats all
so putting it on a fixed timestep should 100% resolve your problem with lag
should i change every deltatime with fixedeltatime then
everything that uses some kind of velocity and acceleration, probably
by the way just changing deltaTime for fixedDeltaTime doesn't do anything good
you need to move it to the fixed update
yea im also doing that
thank you
SO FUCKING much
but its not solved yet
i still have the problems with the mouse.,,
its also exaggerated with framerate
the mouse?
yea mouse input
float xMouse = -Input.GetAxisRaw("Mouse X");
float yMouse = -Input.GetAxisRaw("Mouse Y");
tempPosMouse = new Vector3(xMouse, yMouse, Mathf.Abs(Input.GetAxis("Vertical") / 3)) * currentSway / 70f;
tempMouse = new Vector3(yMouse, -xMouse, xMouse / 4) * currentSway * 3f;
should i put a fixeddeltatime on that also?
sorry, i have to go for an hour or so
if currentSway takes some input from somewhere else then probably you want to do this logic in the fixed update
ill be back
its normal that these values are bigger with a larger update though, because your mouse moves further
you may want to scale any delta inputs with deltatime at some point, but not if they're absolute values of course
i dont remember what GetAxisRaw("Mouse X") represents
still have the mouse problem...
goes too fast when its low fps goes too slow when its high fps
how are you inputting your mouse values to the fixed update logic?
float xMouse = -Input.GetAxis("Mouse X");
float yMouse = -Input.GetAxis("Mouse Y");
tempPosMouse = new Vector3(xMouse, yMouse, Mathf.Abs(Input.GetAxis("Vertical") / 3)) * currentSway / 70f;
tempMouse = new Vector3(yMouse, -xMouse, xMouse / 4) * currentSway * 3f;
then i use the spring system to make the values spring
mouse = SpringSystem.Update(
mouse,
ref mouseVelocity,
tempMouse,
Time.fixedDeltaTime,
freq: 2f,
damp: .2f);
positionMouse = SpringSystem.Update(
positionMouse,
ref positionMouseVelocity,
tempPosMouse,
Time.fixedDeltaTime,
freq: 2f,
damp: .3f);
okay, so at low framerate, you have a big movement followed by multiple frames of acceleration
at high framerate, you have multiple smaller movements, each followed by a frame of acceleration
so the accumulated velocity can be be much larger in the first case than in the second
which is the difference you see
a higher velocity means you will overshoot further
maybe you can try to clamp the magnitude of your velocity and/or acceleration to some reasonable values
so you want me to normalize it?
another possibility is to attach timestamps to your input values, and interpolate them before using them in the fixed update
no, clamp the magnitude
doesnt that mean that when theres lower fps itll be at the lowest clamp and then vice versa
if the FPS is low, your acceleration and velocity will be higher than with a higher FPS
so if you avoid the velocity and/or acceleration to become bigger than a certain value, when the values would become very high in the low FPS case, they will instead not go higher
so the movements will be more similar
I think this alternative solution can also work, but it's a little harder than just Vector3.ClampMagnitude
so try that first imo
tempMouse = Vector3.ClampMagnitude(tempMouse, 1f);
tempPosMouse = Vector3.ClampMagnitude(tempPosMouse, .1f);
like this right?
cause theres still a difference
I was thinking to clamp the velocity and the acceleration, not your mouse positions
are they mouse positions, Mouse X and Mouse Y ? or are they mouse position deltas?
ah, I see it is delta !
so what do i need to do
i know you said something about velocity and acceleration but idk about that
well if it is a delta, you should multiply it by the fixed delta time in this case
(and probably multiply it by 50 or so to get a similar result as before)
at slow framerates you are applying the entire movement for multiple fixed frames
but at high framerates it's only for one fixed frame
thats where your problem comes from
so not sure that multiplying by fixed delta time fixes it actually
but you need to somehow normalize the input over time
anyway.. gotta go again 😄
NOOOOOOOOOOOO
well id be glad if anyone else could help
this is the issue I think, right
maybe an idea is to make sure all delta values are applied only once
so store a boolean somewhere to say whether the input has been processed this frame or not
and a MouseDeltaX and MouseDeltaY value
in the regular update you set this boolean and you add the raw mouse inputs to the MouseDeltaX/Y values
and then in the fixed update you see if this boolean is set
if it is you use MouseDeltaX/Y to calculate your tempMouse and tempPosMouse, and then set the boolean and the MouseDeltaX/Y to zero
if it is not you calculate tempMouse and tempPosMouse with inputs of value 0
or maybe a simpler idea:
retrieve the input in the Update() and divide the values by the delta time (this normalizes the time)
then use the values in the FixedUpdate(), multiplied by the deltatime (this scales the time to the fixed update timescale)
whattttt
ok so i put the floats in the update. divide by delta time
and then in fixedupdate they are multiplied by deltatime?
yeah
inputs are polled at the start of the frame so they are valid for the duration of that frame
using a delta in the fixed update is never going to be great
(without accounting for the amount of time they are valid for)
basically we change from a delta position per frame to a delta position per second
now its fast at high fps and slow at low fps
arms script:
update()
float yMouse = -Input.GetAxis("Mouse Y");
float xMouse = Input.GetAxis("Mouse X");
mouse = new Vector3(yMouse, xMouse) / Time.deltaTime;
fixedupdate()
mouse *= Time.deltaTime;
gunbasescript:
update()
float xMouse = -Input.GetAxis("Mouse X") / Time.deltaTime;
float yMouse = -Input.GetAxis("Mouse Y") / Time.deltaTime;
tempPosMouse = new Vector3(xMouse, yMouse, Mathf.Abs(Input.GetAxis("Vertical") / 3)) * currentSway / 70f;
tempMouse = new Vector3(yMouse, -xMouse, xMouse / 4) * currentSway * 3f;
fixedupdate()
tempPosMouse *= Time.deltaTime;
tempMouse *= Time.deltaTime;
🤔 so the inverse problem? hum
man this is hard
i dont quite understand why the problem is inverted though
maybe it would be simpler to refactor your logic not to use deltas in the fixed update, but instead make your spring logic use a target position
but also, maybe it's valid to ask the question if you really care that much about lower framerates?
unfortunately i do :(
this isnt about spring logic, when i test without the spring it still does the same just not the spring thing
well the rest of my comment still applies, i dont know where you use it all
maybe it would be simpler to refactor your logic not to use deltas in the fixed update
what do you mean
the problem here is not the springs
the problem is the mouse outputing higher numbers when the framerate is low
yeah but isn't that obvious? if you move 10 centimeters per second, at an FPS of 10 you will move 1 per frame, at an FPS of 100 you will move 0.1 per frame
okay, well if that is all you want to do, then you could just clamp xMouse and yMouse to some maximum value?
well thats not really
no i want the mouse values to be frame INDEPENDENT
well the mouse delta values inherently aren't frame independent
which is why i suggested dividing by delta time
i guess ONLY dividing it by delta time works...??
idk im not seeing much difference when theres lag and not
so i guess it works???
🤔 seeing as how the fixed delta time is constant, multiplying by it should not change the result based on lag or not
but if it works that's nice 😄
float xMouse = -Input.GetAxis("Mouse X") / 120 / Time.deltaTime;
float yMouse = -Input.GetAxis("Mouse Y") / 120 / Time.deltaTime;
multiplying by the fixed delta time is equivalent to dividing by the fixed FPS you have in your project settings for it
do you see any difference?
hard to tell, not much I guess
and when i multiply by fixed deltatime in fixedupdate i can see a difference
i guess that works???????
i have the impression the view is moving further when you have low fps? but i could be wrong
yes thats true i havent worked on it lol
i was so focused on fixing the gun sway
i suspect you may have a coding error somewhere if there is really a difference based on this
i have no idea how to find it
but the difference can also be more exaggerated based on how high your input values are
so you see it less because you divided by 120
man i just wanna fix this
i was thinking of something that causes a wrong delta time to be applied, or applied more than once
but i may be wrong of course, just guessing
do you want me to send the whole block of code or
if the current result is "good enough" for you, I wouldn't spend much more time on it
you're making really good progress. try experimenting with spring parameters to make stuff less.. springy. the stiffness can be in the 10e6 scale. are you using unity physics springs?
i found out its only the input