Create terrain which follows spline curve paths

Hello everyone,

I found a repo:

where author created a tube, which follows specific points and I was wondering if I could do the same, but to create terrain with the exact same behaviour. To be more specific:

this is the effect I’m looking for, where camera moves on scroll and follows the road.

I tried to look for something related, but could not find anything helpful, so I thought that maybe I’m not on a correct path to do this and there’s another way.

Please consider that I am a beginner and update or note will be helpful.

Here is my updated code if that helps (replace everything in index.js)

import * as THREE from "three";
import spline from "./spline.js";

const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );

const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 10);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputColorSpace = THREE.SRGBColorSpace;
document.body.appendChild(renderer.domElement);

window.addEventListener('resize', ()=> {
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize(window.innerWidth, window.innerHeight);
});

const tubeGeo = new THREE.TubeGeometry(spline, 252, 1.65, 36, true);
const edges = new THREE.EdgesGeometry(tubeGeo, 0.2);
const lineMat = new THREE.LineBasicMaterial({ color: 0xcccccc });
const tubeLines = new THREE.LineSegments(edges, lineMat);
scene.add(tubeLines);

function updateCamera(t) {
	const time = t * 0.1;
	const looptime = 10 * 1000;
	const p = (time % looptime) / looptime;
	const pos = tubeGeo.parameters.path.getPointAt(p);
	const lookAt = tubeGeo.parameters.path.getPointAt((p + 0.03) % 1);
	camera.position.copy(pos);
	camera.lookAt(lookAt);
}

let zoomInterval
let t = 0

window.addEventListener("wheel", (e) => {
	zoomInterval && clearInterval(zoomInterval)

	if (e.deltaY < 0) {
		const current = t
		zoomInterval = setInterval(() => {
			t -= 20
			if(current - t == 1200) clearInterval(zoomInterval)
		}, 5);
	}
	else if (e.deltaY > 0) {
		const current = t
		zoomInterval = setInterval(() => {
			t += 20
			if(current - t == -1200) clearInterval(zoomInterval)
		}, 5);
	}
	if(t <= 100) t = 0
})
updateCamera(t)

function animate() {
	requestAnimationFrame(animate);
	updateCamera(t)
	renderer.render(scene, camera)
}
animate();

Thank you in advance and have a great day!

Would theatre.js be what you’re looking for? In title you ask about the terrain, but in the description it seems more like you’re looking for a way to move camera around in a specific way?

1 Like

Thanks a lot for the reply :slight_smile: It will help.