PDA

View Full Version : Derivation of Crytek's "spheremap transform" normals?

raga34
10-07-2014, 08:07 AM
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?

GClements
10-07-2014, 11:13 AM
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.

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

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.

raga34
10-07-2014, 12:14 PM
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.

vinceHuang
10-10-2014, 11:42 PM
I need help: I need the dll and lib files of opengles 3.0, who can provide them for me? Please Send contact me .