Finding the tangent vector of a cubesphere using world coordinates

64 Views Asked by At

TLDR.: I’m trying to find the tangent vector of a cubesphere using only world space coordinates.

Background:

A cubesphere is basically just an inflated cube. It is commonly used to project 2D textures onto a sphere due to its comparatively even pixel density. Cubesphere tangent space coordinates (also known as UVs) are generated using the following HLSL code:

// Default Cubemap using if from IG https://www.shadertoy.com/view/ltl3D8
vec2 Cubemap(vec3 uvw)
{
    // intersect cube
    vec3 n = abs(uvw);
    vec3 v = (n.x>n.y && n.x>n.z) ? uvw.xyz: 
             (n.y>n.z) ?            uvw.yzx:
                                    uvw.zxy;
    // project into face
    vec2 uv = v.yz/v.x;
    
    // Cass Everitt's piecewise quadratic warp to even out pixel density
    // https://github.com/casseveritt/projection/blob/master/envmap.h (Ctrl+F pinch)
    vec2 distort = (1.45109572583 - 0.451095725826*abs(uv));
    uv *= distort;
    
    // rescale to 0-1 range
    return 0.5+0.5*uv;
}

The tangent vector is used together with the normal and bitangent vectors to translate vectors vetween world space and the tangent space of the mapping.

The normal vector just points straight up from the sphere surface and for a cubesphere and spheres in general is just normalize(uvw). The bitangent is perpendicular to the tangent and normal, so it is calculated as cross(Normal, Tangent).

The tangent is a vector that points in the direction of the tangent coordinates’ positive x-axis direction in world space. The bitangent does the same for the y-axis. So if we use a quiver plot to show the vector (1,0) in tangent space, we can see what vector we have to match in world space. Tangent Space Vector (1,0) as blue quiver plot, with white outlines of the cube edges.

There are a few naive solutions:

vec3 normal = normalize(UVW);
vec3 tangent = normalize(vec3(abs(0.5(normal.x)-1),
                normal.x*normal.y*normal.z,
                normal.x));

Final Notes:

I only need the tangent vector for a single side of the cubemap as rotating and flipping it for the other 6 sides is trivial. I’ve searched for information on this topic but haven’t been able to find anything that specifically addresses my problem. Can anyone help me with this tricky geometry problem?

1

There are 1 best solutions below

0
On BEST ANSWER

I found two solutions. You can either solve it with finite difference or derivatives. I have both implemented.

See here my shadertoy implementation.

And here the python script on how I got to the solutions.