This is intended as an efficient and lightweight method for applying a sphere-wrapping texture to a mesh/plane and to display it in a variety of 2d geographic projections.
I wonder if this techique could produce box sides for a cube or skybox? (see Box Side projections below).
Major improvements:
much wider selection of projections, supported by proj4js
optional longitude and latitude lines (“Grid” button)
includes points grid among the available texture options.
Button colors: green: done, yellow: working on it, black: no indices after projecting
workaround for proj4js processing non-decimal degrees for angle parameters.
Debugging features:
occasionally will show pro4js string in a popup window.
Lots of (too many!) console logs
can rotate camera even in “flat map” 2d view. This helps detect the triangle-winding issue (described below).
UVs are calculated from vertex positions so the underlying texture is mapped/stretched linearly within each calculated triangle. Because the underlying texture remains unchanged and UVs are relative to the texture, the calculated UVs also remain unchanged. Only positions are projected/calculated, and mesh indices are generated using only positions that have non-NaN values.
It is generally presumed that the projection is a world view, so all points within the static range of -180 to 180 longitude and -90 to 90 latitude (inclusive) are converted.
There are visual issues with some projected points.
Incontinuity - some projections have incontinuities that result on texture stretching across a map area that is supposed to be empty.
Extents - when projected from outside the expected data range (based on the projection itself), some projected points result in oddly shaped and occasionally-overlapping triangles (on which the texture is placed).
Backward - some conversions result in oppositely-wound triangles, which affect the calculation of normals, so the texture appears on the “back” of those triangles.
“Backward” includes some conversions where a triangle vertex wraps to the other side of the map, which can also result in backward-facing triangles.
Curved Rectangular: Robinson, Mollweide, Sinusoidal, Equal Earth
Circular: Bonne (ish), geos, Tilted, Geocentric, Geostationary Satellite View, Azimuthal equidistant (small overlap), Lambert Azimithal Equal Area (small overlap), North Pole Orthographic, South Pole Orthographic, van der Grinten
Conic: Albers Equal Area Conic (incontinuity), Equidistant Conic, Polyconic
Box sides: frontside, backside, leftside, rightside, topside, bottomside (some of these have small issues of triangle wrapping)
Cassini and Mercator
Cassini and Mercator are supposed to be used within a limited input range. Cassini displays with wild extents and overlapping triangles.
Oblique Mercator has similar issues, plain Mercator less so.
Some projections from proj4js I haven’t fully debugged, they are not available from the interface. And many projections aren’t even included in proj4js.
Possible mitigations (not sure if/when):
input range checking (input clipping?).
triangle vertex wrapping detection.
output clipping and/or output geometry intersect
output wrapping detection (clip, intersect, or adaptive tesselation?)
The code is still a mess, but I’ll eventually make this into a class for use in another project of mine.
Updated to put functions in a class. I’m not fully happy with all the methods defined or the general api, but it’s a start.
There’s a simple test for ultra-narrow triangles, or those facing backwards on the 2d map. Those triangles are not included in the indices array and thus not shown.
I’ve also added a projection to proj4js after loading, to see if I could, called “Space Oblique Mercator.”
There are still some artifacts of wrapping and overlap, but that’s mostly a result of not clipping the input.
The api and code need cleanup and additional testing.