Three.js How to make a camera follow a terrain heightmap?

I have a terrain mountain range with a camera fly view positioned close to the heightmap. The camera is controlled using standard keyboard controls that doesn't allow movement in y axis; it stays on it's set y-axis. Since the terrain is not an even level and randomly renders. How can I get the camera to follow the terrain heightmap? Here is an example. Below is an attempt to add raycaster to scale over the terrain. All code is in the animate function in project. I noticed that when the camera attempts to scale up the terrain. If too steep, it will go straight through. Also, it doesn't follow the terrain as it drops. The camera remains at the highest position.

var raycaster = new THREE.Raycaster(camera.position.clone(), new THREE.Vector3(0, -1, 0)); raycaster.ray.origin.copy(camera.position); var intersections = raycaster.intersectObjects( terrain ); if (intersections.length > 0){ var distance = intersections[0].distance; if(distance > 0 && distance < 10){ camera.position.y= intersections[0].point.y + 20; } }


In this snippet:

if(distance > 0 && distance < 10){ camera.position.y= intersections[0].point.y + 20; }

...intersections with distance > 10 are ignored, but then the camera moves to +20 above the terrain. I suspect that's why it can't follow terrain as it drops. I'm less sure about the "too steep" issue, but that could be similar... try keeping the raycaster at a height that's above the maximum terrain altitude, rather than at the camera's location.

If the issues persist, you may want to include a live demo or an export of your terrain.


Copy the camera.position to a vector and raising vector position.y and setting the raycaster to the vectors.

var castFrom = new THREE.Vector3(); var castDirection = new THREE.Vector3(0,-1,0); var raycaster = new THREE.Raycaster(camera.position.clone(), new THREE.Vector3(0, -1, 0)); castFrom.copy(camera.position); castFrom.y += 1000; raycaster.set(castFrom,castDirection); var intersections = raycaster.intersectObjects( terrain ); if (intersections.length > 0){ camera.position.y = intersections[0].point.y+20; }


  • Three.js Pointerlockcontrols shooting along y-axis
  • Raycasting after dynamically changing Mesh in Three.js
  • Aframe video only plays muted on ios
  • Raycasting and container in Three.js
  • Work around for HTML stripping quotes in quirks mode?
  • AJAX Chat Box Scrolling Up Issue
  • jQuery, Calling multiple animations in a row on click
  • Change the width of the JQM panels
  • How to trick Node.js to load .js files as ES6 modules?
  • Variant from android-autofittextview library : scaling makes strange behaviour
  • JS object key sequence
  • How to control Trigger state (Pause, Play) using code (not just buttons)
  • How to replace TouchesBegan with UIGestureRecognizer
  • How to check if DIV element is disabled using jquery
  • Efficient User-Agent Regex to find Safari in Python
  • C++ Single function pointer for all template instances
  • Can I have a variable number of URI parameters or key-value pairs in Laravel 4?
  • WPF version of .ScaleControl?
  • blade.php method outputting it's result to the form
  • How to remove a SwiftyJSON element?
  • D3 get axis values on zoom event
  • Detect when Facebook like button is clicked
  • Test if a set exists before trying to drop it
  • Typescript - Unable to get 'import' statement to function
  • Django: Count of Group Elements
  • Fill an image in a square container while keeping aspect ratio
  • Running a C# exe file
  • Acquiring multiple attributes from .xml file in c#
  • Angular 2 constructor injection vs direct access
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Java static initializers and reflection
  • Android Google Maps API OnLocationChanged only called once
  • How can I remove ASP.NET Designer.cs files?
  • Running Map reduces the dimensions of the matrices
  • Binding checkboxes to object values in AngularJs
  • UserPrincipal.Current returns apppool on IIS
  • java string with new operator and a literal
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?