Sphere mapping

hi,

Our engine lets you generate texture coordinates using Sphere mapping.
When using hardware acceleration the code looks something like this…

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

Nothing too exciting there.

Now I am trying to write a software implementation of this, as there are some situations where I need to manipulate the generated texture coordinates. It also will provide a handy fallback in cases where broken drivers produce bad results.

I started with the OpenGL reference implementation for Sphere mapping, but I end up with slightly different texture coords to the ones generated on the hardware (the image looks almost right, but is clearly wrong in places). Here is the source I am using.

// generate the texture coordinates for every vertex
for (i=0; i<r.output.numverts; i++)
{
// transform normal to eye space : n
// transform vertex to eye space : u
// normalise vertex (gets eye to vertex direction) : u
// reflected vector r = u - 2(u.n)n
// m = 2 * sqrt(rxrx + ryry + (rz+1)*(rz+1))
// s = (rx / m) + 0.5
// t = (ry / m) + 0.5

    mat4_RotateVec3(r.modelview_inverse_transpose, normals[i], n);
    mat4_TranslateRotateVec3(r.modelview, r.xyz[i], u);
    vec3_Normalise(u);
    twonu = 2.0f * vec3_dotproduct(n, u);
    rx = u[0] - twonu * n[0];
    ry = u[1] - twonu * n[1];
    rz = u[2] - twonu * n[2];
    m = 2 * com_sqrt(rx*rx + ry*ry + (rz+1)*(rz+1));
    if (m)
    {
        dst->s = rx / m + 0.5f;
        dst->t = ry / m + 0.5f;
    }
    else
    {
        dst->s = 0.5f;
        dst->t = 0.5f;
    }

    dst++;
}

Can anyone spot anything that seems to be wrong with this?

MrFSAA,

Have you tried normalizing n after transforming it into eye space? The reflection equation requires a unit length normal to be correct.

Otherwise everything there looks good to me.

Thanks -
Cass

Cass,

I had not tried that to be honest. I have just added the appropriate normalisation and it made no difference. Thanks for the suggestion though.

I am going to add a sphere to the scene next, as that might shed some light on exactly what form the error is taking.

Adding the sphere helped work things out.

The reason it was not working is slightly embarassing to be honest. The xyz data it was was referencing was not the xyz data for the model we were rendering. It was using xyz data from a random recent model that had a vertex deformation applied to it. Sigh.

So if anyone else if after a software implementation for sphere mapping the one above seems to work fine. Add the extra normalisation that Cass suggested though.