Any advice updating camera position smoothly along CatmullRomCurve3?

Hey there,

There’s a live version of the scene here.

I have a camera that’s set to move on page scroll, and the camera’s movement has been stuttering noticeably for me, especially when scrolling either very slowly or very quickly. I’m trying to figure out why that’s happening as much as it sometimes is.

I’m setting the camera position using this call in the renderer…

camera.position.copy( setCameraPosition() );

…which is referencing a pretty simple function that looks like this, which positions the camera along a CatmullRomCurve3 using the scroll percentage:

setCameraPosition = function() {
    let p = (getScrollPercent() / 100);
    let position = pathCurve.getPointAt( p );
    return position;
}

I’m also setting the camera’s lookAt in the renderer with this bit…

if (model) camera.lookAt( setPointInModel(.5,.8,.5) );

…which references this function, which sets a focal point relative to the GLTF model I’ve loaded in:

setPointInModel = function( rangeX, rangeY, rangeZ ) {
	let minArray = [], maxArray = [];
	boundingBoxFinal.min.toArray( minArray );
	boundingBoxFinal.max.toArray( maxArray );

	let xOut = THREE.Math.lerp( minArray[0], maxArray[0], rangeX );
	let yOut = THREE.Math.lerp( minArray[1], maxArray[1], rangeY );
	let zOut = THREE.Math.lerp( minArray[2], maxArray[2], rangeZ );

	let output = new THREE.Vector3( xOut, yOut, zOut );
	return output;
}

Any idea why the camera position is stuttering on scroll? Is it that I’m not using a tweening library? Is it that the GLTF is too big? Has my pixel-addled brain missed something obvious?

Thanks for any help you feel like giving.

Best,
Shane

Your example works really well for me, however I have smooth scrolling in my browser. The issue could be caused by browsers without smooth scrolling, which tweening could help

If I click and drag the scrollbar quickly I get slight stutter in the model, which I believe can be fixed by swapping these two lines in your render loop.

// If the model's loaded, set the camera to look at a given point in it
if (model) camera.lookAt( setPointInModel(.5,.8,.5) );

// Set camera to position
camera.position.copy( setCameraPosition() );

to become:

// Set camera to position
camera.position.copy( setCameraPosition() );

// If the model's loaded, set the camera to look at a given point in it
if (model) camera.lookAt( setPointInModel(.5,.8,.5) );

This way the camera will move before looking at the model which should help keep it in the center of view.
Does that help?

1 Like

That seems to have solved it! Thanks for your help, Clark.