worldAtDepth function
WorldAtDepth / WorldAt: the point uv is looking at, depth metres
along the view axis.
The reader's half of what viewDepth writes, and one copy for the two
passes that need it — ssao.frag and reflections.frag transcribe the same
six lines, and two copies of a reconstruction is two chances to reconstruct
somewhere different.
Both ends of the ray are unprojected, rather than starting it at eye.
An orthographic camera's rays are parallel and meet nowhere, so a ray from
the camera position is not the ray the pixel looks along, and every point an
isometric scene reconstructed would land somewhere it is not. Under a
perspective camera the two agree, so this costs one matrix multiply and buys
a projection.
inverse carries the framebuffer origin, so v runs the other way from
clip-space y — see UvFromNdc.
Implementation
Vector3 worldAtDepth(
Matrix4 inverse,
Vector3 eye,
Vector3 axis,
double u,
double v,
double depth,
) {
final (:origin, :along) = pixelRay(inverse, u, v);
return origin +
along * ((depth - (origin - eye).dot(axis)) / along.dot(axis));
}