imageProjection

Optional 4x4 matrix mapping a world WGS84-ECEF position to image clip space, applied per-fragment on the terrain surface. When non-null the shape switches from the planar 2D-homography path (which approximates as if the four corners lie on a flat plane) to a true 3D camera-frustum projection path that's mathematically correct over arbitrary relief.

Build via earth.worldwind.geom.CameraPose.setToLookAt (lat/lon/alt + look-at target + FOV) or earth.worldwind.geom.CameraPose.setFromPlatformAndSensorPose (KLV-style platform yaw/pitch/roll composed with sensor relative angles).

Trade-offs:

  • Cost: one mat4vec4 per fragment per terrain tile, plus a per-tile CPU recompute, versus one mat3vec3 per fragment for the homography path. The 3D path also breaks the surface-drawable batching so each shape is its own draw call.

  • Quality: the homography is exact only on a flat ground plane; the 3D path is exact regardless of terrain relief. For sub-km drone footprints over typical rolling terrain the visible difference is small. For 10+ km photo footprints over mountainous terrain the homography distorts noticeably.

  • JS / WebGL: this path renders incorrectly on JS - browser GLSL compilers produce wrong per-fragment results for typical perspective mat4 * vec4 regardless of highp, RTE source-shifting, fp64 emulation, or WebGL 2 + GLSL ES 3.00 migration. JS callers should leave imageProjection null and rely on the homography path (which renders the same drone footage correctly via the four ground-corner KLV tags). JVM and Android render the 3D path as written. Full investigation log and remaining options: docs/webgl-3d-projection-investigation.md.

null (default) keeps the homography path with its lower per-frame cost.