|
Author Topic:   Environment Mapping
LDA Seumas
unregistered
posted September 17, 1999 03:52 AM           
I've posted this to mailing lists in the past, but I thought I'd post it here to make it a little more accessible. This is code to generate texture coordinates for world-aligned spherical environment mapping, which is a great way to get real or faked reflections, phong style lighting, or just really cool looking surfaces.

out is a pointer to two floats which will hold the U and V texture coordinates for the point, vert is 3 floats holding the point's object-space position, norm is the vertex's object space normal vector, campos is the camera position _transformed into object space_, and envbasis is a 3x3 matrix that is used to control the alignment of the environment map. The general case is to set envbasis to be the object's rotation matrix, which will cause the spherical environment map to act as if aligned to the world, with the singularity facing downwards. You can fiddle with the envbasis matrix to rotate the environment map around independently of the object or the world, and if you set it to be an identity matrix, the environment map becomes locked to the object's orientation.

__forceinline void SphericalYEnvMapCoords(float *out, Vec3 vert,
Vec3 norm, Mat3 envbasis, Vec3 campos){
//r = u - 2 * n * (n dot u)
Vec3 tv, r;
SubVec3(vert, campos, u);
NormVec3(u);
ScaleVec3(norm, 2.0f * DotVec3(norm, u), tv);
SubVec3(u, tv, r);
//
Vec3 r2 = {r[0] + envbasis[0][1],
r[1] + envbasis[1][1],
r[2] + envbasis[2][1]};
float im = 1.0f / (2.0f * LengthVec3(r2));
//1 / (2 * sqrt((rx+envyx)^2 + (ry+envyy)^2 + (rz+envyz)^2))
//
out[0] = (r[0] * envbasis[0][0] +
r[1] * envbasis[1][0] +
r[2] * envbasis[2][0]) * im + 0.5f;
out[1] = (r[0] * envbasis[0][2] +
r[1] * envbasis[1][2] +
r[2] * envbasis[2][2]) * im + 0.5f;
}

Note that NormVec3() normalizes a vector to length 1.0, which can use a square root and a divide, or more sneaky methods.

Comments? Questions?

------------------
-- Seumas McNally, Lead Programmer, Longbow Digital Arts

IP:

LDA Seumas
unregistered
posted September 17, 1999 03:55 AM           
Oh, and I should also clarify that SubVec3(a, b, c) is equivalent to c = a - b. That is, a minus b, with the result stored in c.

------------------
-- Seumas McNally, Lead Programmer, Longbow Digital Arts

IP:

LDA Seumas
unregistered
posted September 17, 1999 01:33 PM           
To be complete, ScaleVec3(a, b, c) scales vector a by float b and puts the result in vector c.

I also just realized I have two square roots and two divides in there for each vertex... Yuck. If anyone has a trick for removing some of that pain, or perhaps a good square root approximation, I'd appreciate hearing about it.

And have a look at this link mentioned by Neal Tringham for a good overview of environment mapping in general:
http://reality.sgi.com/blythe/sig99/advanced99/notes/node174.html

------------------
-- Seumas McNally, Lead Programmer, Longbow Digital Arts

IP: