Topic : A Texture Mapping Technique
Author : Joshua Cantrell
Page : << Previous 2  
Go to page :

[(d * Py) / Pz]
   [0, 0, 0, 1]   [Pz]   [  1   ]   [    1 / Pz   ]
   [0, 0, 1, 0]   [ 1]   [  Pz  ]   [      1      ]

We can now ignore the z-coordinate because it is in orthogonal space, and say that x' = ((d * x) / z), y' = ((d * y) / z), and z' = 0. Rearranging these equations and plugging them into the equation of the plane, we can find out where lines poked through the screen will intersect with the plane and give us the seen point.

Finding the point on the polygon's plane:

Let N = The plane's normal vector.
Let P = Any point on the plane.
Let (Nx*x) + (Ny*y) + (Nz*z) = (Nx*Px + Ny*Py + Nz*Pz) be the equation of
        a plane.

   x' = ((d * x) / z)
   x = (x' * z) / d

   y' = ((d * y) / z)
   y = (y' * z) / d

   (Nx*((x'*z)/d)) + (Ny((y'*z)/d)) + (Nz*z) = (Nx*Px + Ny*Py + Nz*Pz)
   z * (((Nx * x') / d) + ((Ny * y') / d) + Nz) = Nx*Px + Ny*Py + Nz*Pz
   z = (Nx*Px + Ny*Py + Nz*Pz) / (((Nx*x')/d) + ((Ny*y')/d) + Nz)

Now we can plug in a screen coordinate (x', y') and get the point of intersection with the polygon's plane at (x, y, z). Neat.

Transforming from screen space to texture space

The last step to this process is now to put all of our pieces together and try to simplify our equation as much as possible. By using the coordinate found by intersecting the ray from the focus through the polygon's plane, we can translate the intersected point into texture space, which gives us the texture position that is being seen. I'll be using [u,v] to represent the dot product between u and v.

Moving from screen space to texture space:

Let (x', y') = The screen coordinates.
Let P = Any Point on the polygon's plane.
Let T = Texture point in texture coordinates.
Let C = Point on the polygon to be the texture map's origin.
Let N = Normalized vector that is orthogonal to the polygon's plane
Let U = Normalized vector on the polygon's plane that points in the
        direction of increasing x in the texture space.
Let V = Normalized vector on the polygon's plane that points in the
        direction of increasing y in the texture space.

          (x'* z     )        (y'* z     )        (      )
Tx = Ux * (----- - Cx) + Uy * (----- - Cy) + Uz * (z - Cz)
          (  d       )        (  d       )        (      )

d * Tx = Ux*x'*z + Uy*y'*z + Uz*d*z - d*(Ux*Cx + Uy*Cy + Uz*Cz)

       = z*(Ux*x' + Uy*y' + Uz*d) - d*(Ux*Cx + Uy*Cy + Uz*Cz)

       = z*[U,(x', y', d)] - d*[U,C]

z = (Nx*Px + Ny*Py + Nz*Pz) / (((Nx*x')/d) + ((Ny*y')/d) + Nz)

  = [N,P] / [N,(x'/d, y'/d, 1)]

d * Tx = ([N,P] / [N,(x'/d, y'/d, 1)])*[U,(x', y', d)] - d*[U,C]

       = d * ([N,P] / [N,(x', y', d)])*[U, (x', y', d)] - d*[U,C]

Tx = (([N,P] / [N,(x', y', d)]) * [U, (x', y', d)]) - [U,C]

Ty = (([N,P] / [N,(x', y', d)]) * [V, (x', y', d)]) - [V,C]

Tz = 0

This is the basic answer and equation for going from screen to texture coordinates. Something you may want to notice is that you don't have to normalize N because the magnitudes cancel in the division. The way the magnitude of U and V are positioned may have some scaling properties that you like, so those may not have to be normalized either. Otherwise, the rest of the optimization and simplifying is up to you. If you have any ideas, don't be afraid to e-mail me.

Advanced analysis of the result

It would be good to see many of the nice features that appear in the result. The constant in each expression, [U,C] and [V,C] help offset the texture, so you could use these numbers to offset the texture on a polygon's plane. Also notice that [N,P] is duplicated, so it only needs to be calculated once per polygon with the texture centered at point P. The real disturbing fact with the result are the two divisions necessary per point. Division is slow, and cannot be easily approximated, so it would be nice to somehow dodge doing it for every point.

As of now, my method is just a simple linear interpolation between two calculated texture points on a linear scanline. As long as the amount of interpolated points stays small, it is hard to notice the difference between a non-interpolated texture and an interpolated one. Part of this is caused by the fact that everything is straight when you peer directly at the plane of a polygon and when the polygon's face isn't directly pointed at you, the points become more crammed. This is advantageous because you are more likely to notice discrepancies in objects that are much easier to see (those head on), and those are the objects less effected by the division by z.

One colleague, Andrew Jewett, suggests that it may be possible to have general line scanlines that follow the contour of changing z on a 3D plane. This would allow you to do only one division by z per scanline. If the lines could be lined up properly, not to overlap, then it may beable to provide a quick method of having near-perfectly drawn textured polygons. (I'll take a look at this method when I have time.)

Applying the equations in a program

Even with equations, there still has to be a method of using the practically. Not only can this possibly help one better understand the usefulness of the results, but also feel the joy of tangible success! To complement this study, I have produced a WWW page on Applying the Texture Mapping Technique.

Special thanks to:
Professor Forsyth, for teaching CS184 where much of what I learned went into the derivation of this technique. All of the Matrix techniques came from what I learned during lecture.

Page : << Previous 2