#Problems with lerping and fps

1 messages · Page 1 of 1 (latest)

sick citrus
#

I know my code is a complete mess and is really unoptimized but whatever. How do I prevent the things in the video to happen?

#

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

flint portal
#

!code

coarse sirenBOT
flint portal
#

anyways this is a case of wrong lerp

#

that's your issue

#

you're also lerping a rotation instead of slerping it

sick citrus
#

thanks ill trythis

sick citrus
white grail
#

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

sick citrus
#

still tryna figure out how lerp works its so hard to wrap my head around stuff

flint portal
#

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

sick citrus
#

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);
flint portal
#

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

sick citrus
#

idk what to call them :(

flint portal
#

there's a ton of ways to describe smoothing

#

you could say it's smoothtowards or whatever

sick citrus
#

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

flint portal
#

you can right click > rename symbol or use F2

#

it'll update the references too

flint portal
sick citrus
flint portal
#

modifying velocity by acceleration in a unit time, and modifying position by velocity in a unit time

sick citrus
flint portal
#

not sure what im supposed to be looking at here

flint portal
sick citrus
sick citrus
#

position recoil i mean

#

and also

#

the mouse movement

flint portal
#

do you have deltaTime applied to the mouse movement

#

(you shouldn't)

sick citrus
#

i dont have it applied

flint portal
#

if the mouse movement on its own seems to be framerate dependant, the issue with recoil might be related to that

sick citrus
#

hold on how do i

#

thats the whole sway update thingy

#

its called in update

#

those are for the arms though

#

this is for the gun itself

white grail
#

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)

flint portal
lyric comet
lyric comet
#
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

flint portal
#

by definition, it isn't a lerp

#

the L stands for linear. this isn't linear

#

it's not that deep

lyric comet
#

Sure. We can argue about semantics and definitions, but that doesnt help anyone here

flint portal
#

i'd argue separating the concepts helps a lot

sick citrus
#

i still have problems with the spring system

#

idk its weird

sick citrus
sick citrus
#

bump

sick citrus
#

its still really exaggerated on low fps...,.,

lyric comet
#

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

sick citrus
lyric comet
#

it's for everything that requires a fixed update

sick citrus
#

im so close to giving up

lyric comet
#

put it on a fixed timestep

#

your problems will be gone

sick citrus
#

which

lyric comet
#

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

lyric comet
sick citrus
#

i put the spring updates in fixedupdate
it didnt do anything

lyric comet
#

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 ...

lyric comet
#

so you can tweak it to behave as you want

lyric comet
#

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

sick citrus
#

oh man this is gonna take a while isnt it

lyric comet
#

i really dont see why

#

what does your "lag" option do?

sick citrus
#

im not a master coder i dont have a clue what youre talking about

sick citrus
lyric comet
#

right

sick citrus
#

its a debug thats all

lyric comet
#

so putting it on a fixed timestep should 100% resolve your problem with lag

sick citrus
#

should i change every deltatime with fixedeltatime then

lyric comet
#

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

sick citrus
#

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

lyric comet
#

the mouse?

sick citrus
#

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?

lyric comet
#

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

sick citrus
#

no problem

#

gl with whatever youre doing

lyric comet
# sick citrus its also exaggerated with framerate

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

sick citrus
#

still have the mouse problem...

#

goes too fast when its low fps goes too slow when its high fps

lyric comet
#

how are you inputting your mouse values to the fixed update logic?

sick citrus
#

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);
lyric comet
#

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

sick citrus
#

so you want me to normalize it?

lyric comet
#

another possibility is to attach timestamps to your input values, and interpolate them before using them in the fixed update

#

no, clamp the magnitude

sick citrus
lyric comet
#

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

lyric comet
#

so try that first imo

sick citrus
#
tempMouse = Vector3.ClampMagnitude(tempMouse, 1f);
tempPosMouse = Vector3.ClampMagnitude(tempPosMouse, .1f);
#

like this right?

#

cause theres still a difference

lyric comet
#

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?

sick citrus
#

its.. uhh input.getaxis

#

thing

lyric comet
#

ah, I see it is delta !

sick citrus
#

so what do i need to do

#

i know you said something about velocity and acceleration but idk about that

lyric comet
#

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

sick citrus
#

ohh

#

hold on im testing rn

lyric comet
#

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 😄

sick citrus
#

well id be glad if anyone else could help

lyric comet
# lyric comet at slow framerates you are applying the entire movement for multiple fixed frame...

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)

sick citrus
#

ok so i put the floats in the update. divide by delta time
and then in fixedupdate they are multiplied by deltatime?

lyric comet
#

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

sick citrus
#

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;
lyric comet
#

🤔 so the inverse problem? hum

sick citrus
lyric comet
#

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?

sick citrus
lyric comet
#

well the rest of my comment still applies, i dont know where you use it all

sick citrus
#

use what?

#

the spring system?

lyric comet
#

maybe it would be simpler to refactor your logic not to use deltas in the fixed update

sick citrus
#

idk how to do that

#

im talking about the mouse man not the springs

lyric comet
#

what do you mean

sick citrus
lyric comet
#

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

sick citrus
#

here im printing out xMouse

#

from the gunbasescript

lyric comet
#

okay, well if that is all you want to do, then you could just clamp xMouse and yMouse to some maximum value?

sick citrus
#

no i want the mouse values to be frame INDEPENDENT

lyric comet
#

well the mouse delta values inherently aren't frame independent

#

which is why i suggested dividing by delta time

sick citrus
#

idk im not seeing much difference when theres lag and not

#

so i guess it works???

lyric comet
#

🤔 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 😄

sick citrus
#
float xMouse = -Input.GetAxis("Mouse X") / 120 / Time.deltaTime;
float yMouse = -Input.GetAxis("Mouse Y") / 120 / Time.deltaTime;
lyric comet
#

multiplying by the fixed delta time is equivalent to dividing by the fixed FPS you have in your project settings for it

sick citrus
lyric comet
#

hard to tell, not much I guess

sick citrus
#

and when i multiply by fixed deltatime in fixedupdate i can see a difference

#

i guess that works???????

lyric comet
#

i have the impression the view is moving further when you have low fps? but i could be wrong

sick citrus
#

i was so focused on fixing the gun sway

lyric comet
sick citrus
#

i have no idea how to find it

lyric comet
#

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

sick citrus
#

man i just wanna fix this

lyric comet
sick citrus
#

do you want me to send the whole block of code or

lyric comet
#

if the current result is "good enough" for you, I wouldn't spend much more time on it

mystic basin
# sick citrus do you see any difference?

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?

sick citrus