Jump to content

PixiJS Jitter


Merlot
 Share

Recommended Posts

Hello everyone! My first post here.

I'm trying to build a fixed timestep to align my server with clients on updates.
I've been searching for a lot of info online before posting this. In my opinion this should work fine, I have no idea why it's still creating small jitters.

The algo on a big scale is something like:

PixiTickerLoop {
	let elapsed = PIXI.Ticker.shared.elapsedMS
        if (elapsed > 1000) elapsed = this.frameDuration
        this.lag += elapsed

        while (this.lag >= this.frameDuration) {  

            //Update the logic
            this.updateInputs()

            //Reduce the lag counter by the frame duration
            this.lag -= this.frameDuration
        }

        const lagOffset = this.lag / this.frameDuration
        this.interpolateSpaceships(lagOffset)
}


Inside the updateInputs I have something like:

this.lerpX.increaseLerp(this._velocity.x)
this.lerpY.increaseLerp(this._velocity.y)

At this point the velocity is just a constant, to keep things simple. Eg: 10

Now, lerpX and lerpY are a class made the following way:

export class Lerp {

	private from: number = 0
	private to: number = 0
	private startTime: number = 0
	private frame: number = 0
	private onFrame: (value: number) => void
	public logger: boolean = false

	constructor(from: number, onFrame: (value: number) => void) {
		this.onFrame = onFrame
		this.from = from
	}

	increaseLerp(to: number, time: number) {
		this.frame += 1

		if (this.startTime != 0) {
			const duration = time - this.startTime
			if (this.logger) console.log(`[Lerp] Frame length - ${duration} - ${this.frame}`)
		}

		this.startTime = time
		if (this.frame > 1) this.from = this.to
		this.to = this.from + to
	}

	newFrame(lagOffset: number) {
		if (!this.needsNewFrame()) return

		// const value = this.from + (this.to - this.from) * lagOffset
		const value = Maths.lerp(this.from, this.to, lagOffset)
		if (this.logger) console.log(`[Lerp] From: ${this.from}, To: ${this.to} = ${value} ( ${lagOffset} )`)

		this.onFrame(value)
	}

	needsNewFrame() {
		return this.startTime > 0 && Math.abs(this.to - this.from) > 0.001
	}

	reset(current: number) {
		this.startTime = 0
		this.from = current
		this.to = 0
		this.frame = 0
	}

}

 

Inside the main loop, there is a function that interpolates data.
That will call "newFrame" which will then use the callback to update the render position.

The logs that a simple run produces are like this: ( considering velocity = 10 )

 

Quote

[UpdateInputs] 1671983837313
SpaceshipSprite.ts:236 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 41.66500000000087 - 2
Lerp.ts:35 [Lerp] From: 11093.168160324418, To: 11103.168160324418 = 11093.99716032442 ( 0.0829000000000201 )
BulletSprite.ts:27 [Bullet][Position][Update]
Lerp.ts:35 [Lerp] From: 11093.168160324418, To: 11103.168160324418 = 11097.330360324417 ( 0.4162199999999689 )
Lerp.ts:35 [Lerp] From: 11093.168160324418, To: 11103.168160324418 = 11100.663560324418 ( 0.7495399999999904 )
Lerp.ts:35 [Lerp] From: 11093.168160324418, To: 11103.168160324418 = 11102.330160324418 ( 0.9162000000000375 )
GameManager.ts:229 [UpdateInputs] 1671983837366
SpaceshipSprite.ts:236 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 58.33099999999831 - 3
Lerp.ts:35 [Lerp] From: 11103.168160324418, To: 11113.168160324418 = 11105.663360324419 ( 0.24951999999998634 )
BulletSprite.ts:27 [Bullet][Position][Update]
Lerp.ts:35 [Lerp] From: 11103.168160324418, To: 11113.168160324418 = 11107.329960324418 ( 0.41618000000003347 )
Lerp.ts:35 [Lerp] From: 11103.168160324418, To: 11113.168160324418 = 11110.663160324419 ( 0.7494999999999823 )
GameManager.ts:229 [UpdateInputs] 1671983837407
SpaceshipSprite.ts:236 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 41.66500000000087 - 4
Lerp.ts:35 [Lerp] From: 11113.168160324418, To: 11123.168160324418 = 11113.996360324418 ( 0.08282000000000381 )
BulletSprite.ts:27 [Bullet][Position][Update]
Lerp.ts:35 [Lerp] From: 11113.168160324418, To: 11123.168160324418 = 11115.662960324418 ( 0.2494799999999782 )
Lerp.ts:35 [Lerp] From: 11113.168160324418, To: 11123.168160324418 = 11120.662760324418 ( 0.7494599999999741 )
Lerp.ts:35 [Lerp] From: 11113.168160324418, To: 11123.168160324418 = 11122.329360324418 ( 0.9161200000000213 )
GameManager.ts:229 [UpdateInputs] 1671983837465
SpaceshipSprite.ts:236 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 49.99799999999959 - 5
Lerp.ts:35 [Lerp] From: 11123.168160324418, To: 11133.168160324418 = 11123.995960324417 ( 0.08277999999999565 )
BulletSprite.ts:27 [Bullet][Position][Update]
Lerp.ts:35 [Lerp] From: 11123.168160324418, To: 11133.168160324418 = 11127.329160324418 ( 0.4161000000000172 )
Lerp.ts:35 [Lerp] From: 11123.168160324418, To: 11133.168160324418 = 11130.662360324417 ( 0.749419999999966 )
GameManager.ts:229 [UpdateInputs] 1671983837512
SpaceshipSprite.ts:236 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 49.99799999999959 - 6
Lerp.ts:35 [Lerp] From: 11133.168160324418, To: 11143.168160324418 = 11133.995560324418 ( 0.0827399999999875 )
BulletSprite.ts:27 [Bullet][Position][Update]
Lerp.ts:35 [Lerp] From: 11133.168160324418, To: 11143.168160324418 = 11137.328760324417 ( 0.41606000000000903 )
Lerp.ts:35 [Lerp] From: 11133.168160324418, To: 11143.168160324418 = 11140.661960324418 ( 0.7493800000000306 )
Lerp.ts:35 [Lerp] From: 11133.168160324418, To: 11143.168160324418 = 11142.328560324417 ( 0.916040000000005 )

 

Link to comment
Share on other sites

The jitter appears when the frame length becomes unstable. I managed to get this from logs.
The normal frame length should be 50. As soon as the length changes, it jitters. 
Eg below: 50, 67,43,39 then back to 51 again. As long as it stays between 49-51, it's ok.
 

Quote

[UpdateInputs] 1672057632736
SpaceshipSprite.ts:244 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 50 - 73
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13779.539579264163 ( 0.16442000000000007 )
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13781.206179264162 ( 0.33108000000001087 )
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13782.872779264162 ( 0.49773999999998525 )
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13784.539379264163 ( 0.664399999999996 )
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13786.205979264161 ( 0.8310600000000068 )
Lerp.ts:35 [Lerp] From: 13777.895379264162, To: 13787.895379264162 = 13787.872579264162 ( 0.9977200000000175 )
GameManager.ts:227 [UpdateInputs] 1672057632803
SpaceshipSprite.ts:244 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 67 - 74
Lerp.ts:35 [Lerp] From: 13787.895379264162, To: 13797.895379264162 = 13792.872379264163 ( 0.49770000000001346 )
Lerp.ts:35 [Lerp] From: 13787.895379264162, To: 13797.895379264162 = 13794.538979264162 ( 0.6643599999999878 )
GameManager.ts:227 [UpdateInputs] 1672057632846
SpaceshipSprite.ts:244 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 43 - 75
Lerp.ts:35 [Lerp] From: 13797.895379264162, To: 13807.895379264162 = 13799.538779264163 ( 0.16433999999998378 )
Lerp.ts:35 [Lerp] From: 13797.895379264162, To: 13807.895379264162 = 13801.205379264162 ( 0.3309999999999945 )
Lerp.ts:35 [Lerp] From: 13797.895379264162, To: 13807.895379264162 = 13802.871979264162 ( 0.4976600000000053 )
Lerp.ts:35 [Lerp] From: 13797.895379264162, To: 13807.895379264162 = 13806.205179264161 ( 0.8309799999999905 )
Lerp.ts:35 [Lerp] From: 13797.895379264162, To: 13807.895379264162 = 13807.871779264162 ( 0.9976400000000012 )
GameManager.ts:227 [UpdateInputs] 1672057632885
SpaceshipSprite.ts:244 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 39 - 76
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13809.538379264162 ( 0.164300000000012 )
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13811.204979264163 ( 0.3309599999999864 )
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13812.871579264163 ( 0.4976199999999972 )
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13814.538179264164 ( 0.664280000000008 )
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13816.204779264162 ( 0.8309400000000187 )
Lerp.ts:35 [Lerp] From: 13807.895379264162, To: 13817.895379264162 = 13817.871379264161 ( 0.997599999999993 )
GameManager.ts:227 [UpdateInputs] 1672057632936
SpaceshipSprite.ts:244 [Spaceship] Move called
Lerp.ts:22 [Lerp] Frame length - 51 - 77
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13819.537979264163 ( 0.16426000000000385 )
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13821.204579264162 ( 0.33092000000001465 )
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13822.871179264162 ( 0.49757999999998903 )
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13824.537779264163 ( 0.6642399999999998 )
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13826.204379264163 ( 0.8309000000000105 )
Lerp.ts:35 [Lerp] From: 13817.895379264162, To: 13827.895379264162 = 13827.870979264162 ( 0.9975599999999849 )

 

Link to comment
Share on other sites

Ok, time to close this thread. Even though I didn't get any help, it helped me track my progress and research. Hopefully it will help some folks in the future.

 

So.. drum rolls please! Time to reveal the solution:

 

const ticker = new PIXI.Ticker();

// The number of frames to use for smoothing
const smoothingFrames = 10;

// The smoothed frame duration
let smoothedFrameDuration = 0;

ticker.add((deltaTime) => {
  // Add the current frame duration to the smoothing array
  smoothedFrameDuration = (smoothedFrameDuration * (smoothingFrames - 1) + deltaTime) / smoothingFrames;

  // Update the game logic here
  // Use the smoothed frame duration instead of the raw deltaTime value
});

ticker.start();

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...