I'm building a tiled slippy map globe in THREE.js much like Cesium. The issue I've run into is that when, at high zoom levels, I rotate the Perspective/OrbitControls camera, the tiles jitter/shake. It's probably a precision issue but I don't know how to work around this one.
How I'm projecting tiles:
- Create a THREE.PlaneBufferGeometry centered at the origin of the
parent planet (an Object3D at (0, -planetRadius, 0) ). - Project each of the plane's attribute vertices (one by one) to a point matching it's correct latitude, longitude and elevation (lonLatToVector3()).
- I then have a camera that can zoom in on a plane/tile and the distance from the camera to the tile determines which zoom level tiles to render.
Things that don't solve the issue:
- A near clipping plane of 1.
- A close far clipping range (such as near: 1, far: 2).
- A logarthmic or non-logarthmic depth buffer.
- Keeping the camera lookat at (0,0,0).
- Panning rotating the planet instead of moving the camera.
- Scaling up or down the entire world.
This question most relates to this stackoverflow question and I've modified that fiddle to better represent the core of my issue:
https://jsfiddle.net/6qfaf5h0/
for (var p = 0; p < mesh.geometry.attributes.position.array.length; p += 3) {
var xyzPos = lonLatToVector3(0 + (((p / 3) % tileRes) / (tileRes - 1)) * anglePlane,
0 + (parseInt((p / 3) / tileRes) / (tileRes - 1)) * anglePlane,
0);
mesh.geometry.attributes.position.array[p] = xyzPos.x;
mesh.geometry.attributes.position.array[p + 1] = xyzPos.y;
mesh.geometry.attributes.position.array[p + 2] = xyzPos.z;
//mesh.geometry.attributes.position.array[p + 2] = 0; //<- uncommenting fixes shake but I need this axis
}
I want a mesh with an anglePlane < 0.01 that (when zoomed in to a point where only a few vertices are visible) doesn't shake.
Other possibly helpful notes:
- Sprites don't shake despite using the same projection algorithm.
- In some cases even a zoomed in flat (elevation = 0) plane can look all wavy.
Any help would be greatly appreciated.