Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThreeJS Object3D flickers when tweening with yoyo turned on. #681

Closed
NyaNguyen opened this issue Feb 22, 2024 · 11 comments
Closed

ThreeJS Object3D flickers when tweening with yoyo turned on. #681

NyaNguyen opened this issue Feb 22, 2024 · 11 comments
Labels

Comments

@NyaNguyen
Copy link

NyaNguyen commented Feb 22, 2024

ok, so I tested this and was able to reproduce the issue with this example:

import * as THREE from 'three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

const tween = new TWEEN.Tween(cube.position)
    .to({ x: 10 }, 4000)
    .easing(TWEEN.Easing.Linear.None)
    .yoyo(true)
    .repeat(Infinity)
    .start();

camera.position.z = 20;

const animate = function () {
    requestAnimationFrame(animate);

    TWEEN.update();

    renderer.render(scene, camera);
};

animate();

We can see the Object3D flickers each time it bounces back and forth. I'm not too sure if this is a TweenJS bug or there is something I need to do in ThreeJS to ensure the position does not somehow reset.

I attached a quick video of the problem. Tested with Firefox and Edge and got the same issue.

@NyaNguyen
Copy link
Author

VID_20240221_211342.mp4

@mk965
Copy link
Collaborator

mk965 commented Feb 22, 2024

Thanks for your feedback, this is a known issue. #677

@cleverfrog
Copy link

VID_20240221_211342.mp4

Hey @NyaNguyen - is that a cell phone video of a monitor displaying that demo for the flicker - or is that the actual canvas output? It has a cool postprocessing effect :)

@NyaNguyen
Copy link
Author

heh....umm..yeah, it's a cell phone filming the monitor with an overhead light shining on it. The flicker we see if what is actually rendered on the screen. ;D

@trusktr
Copy link
Member

trusktr commented Mar 29, 2024

Until we can fix this, a workaround is to create two tweens, one going in the opposite direction, and chain them.

If you intend to only make it bounce back and forth linearly, another option is to simply increment on each frame like this (instead of using Tween.js):

let pos = 0
let direction = 1
function animate(time) {
  if (pos <= 0) direction = 1
  if (pos >= 1) direction = -1

  pos += direction * 5
}

Where you can replace 5 with a magnitude based on time and the previous time (delta time) for example.

@trusktr trusktr added the Bug label Mar 29, 2024
@NyaNguyen
Copy link
Author

Oh no, a bandage solution! :P Hey, I decided to take a look at the code. Isn't the fix for this simply to move the following code at the bottom before the return true;?

            // properties transformations
            this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value);

Seems to work...

@trusktr
Copy link
Member

trusktr commented Mar 30, 2024

If it works and all tests pass, let's do it! Would you like to open a pull request?

@NyaNguyen
Copy link
Author

As I won't really know what I am doing with branches and stuff, I will abstain from doing any of that. ;D

After testing further, the file I edited was tween.umd.js. I simply copied the first this._updateProperties() method call over to the bottom as shown in the screenshot.

Edit

@humodz
Copy link
Contributor

humodz commented Apr 19, 2024

@NyaNguyen

There's two issues with that fix:

  • the _updateProperties call needs to be added before all three returns in .update()
  • the callbacks (onUpdate, onRepeat, etc) will be called with the values of the previous update. The current behavior is for them to be called after the value is updated, which I tried to preserve in my pull request

@humodz
Copy link
Contributor

humodz commented Apr 19, 2024

@trusktr Do you mind taking a look at #678 when you have the time?

@trusktr
Copy link
Member

trusktr commented May 5, 2024

Fixed in

Released in v23.1.2

@trusktr trusktr closed this as completed May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants