Derivation of Crytek's "spheremap transform" normals?

Crytek’s famous “A bit more deferred” presentation gives the following equations for storing view-space normals in two components:

Storing:


G=normalize(N.xy)*sqrt(N.z*0.5+0.5)

Reconstructing:


N.z=length2(G.xy)*2-1
N.xy=normalize(G.xy)*sqrt(1-N.z*N.z)

But they never say how this was derived, why it works, where it came from, etc.

Any ideas?

Given you’re only interested in unit-length normals, you could almost just store the X and Y components, then reconstruct the Z component via


x^2 + y^2 + z^2 = 1
=> z^2 = 1 - x^2 - y^2
=> z = sqrt(1 - x^2 - y^2)

But there are two problems with that. First, it doesn’t tell you the sign of Z. Second, it’s ill-conditioned when |Z| is small, meaning that the recovered Z may have significant error.

This maps the sphere to a circle such that lines of longitude become radii and lines of latitude become circles. The origin of the circle corresponds to the South pole (0,0,-1), the circumference to the North pole (0,0,1), and the circle of radius sqrt(1/2)=0.707… to the equator (x,y,0). Why the sqrt()? Probably to preserve the density; the area inside the circle of radius sqrt(1/2) is equal to the area outside of it, so the North and South hemispheres map to equal areas.

There are other possible approaches; almost any cartographic projection could be used, and there are plenty of those. This was probably chosen as providing a reasonable balance between accuracy and efficiency.

Thanks, that’s given me enough to go on to dissect it fully.

I’ve actually implemented it and it seems to work well for all inputs, but I don’t like to have essentially magic equations just sitting there unexplained.

I need help: I need the dll and lib files of opengles 3.0, who can provide them for me? Please Send contact me .