Compute geometric surface normals from an elevation grid, encoded as a compact
RG8 buffer (2 bytes/texel) using a hemisphere encoding: only the grid-local
x and z components are stored (mapped to [0, 1]); the consumer reconstructs
y = sqrt(1 - x^2 - z^2).
This replicates the per-fragment normal that SurfaceMaterial's shader derives
from the elevation texture (same four diagonal neighbours, cross products and
hole handling), but pays the cost once on the CPU instead of in every OIT pass.
The result is laid out to match the elevation buffer (row-major, intended for a
flipY = true texture), so it samples 1:1 with the same grid UVs.
Compute geometric surface normals from an elevation grid, encoded as a compact RG8 buffer (2 bytes/texel) using a hemisphere encoding: only the grid-local
xandzcomponents are stored (mapped to [0, 1]); the consumer reconstructsy = sqrt(1 - x^2 - z^2).This replicates the per-fragment normal that
SurfaceMaterial's shader derives from the elevation texture (same four diagonal neighbours, cross products and hole handling), but pays the cost once on the CPU instead of in every OIT pass. The result is laid out to match the elevation buffer (row-major, intended for aflipY = truetexture), so it samples 1:1 with the same grid UVs.