THIS DOCUMENT HAS BEEN CERTIFIED
MEANNESS RATING 10/10

Theory
    Below is a plan view diagram showing a horizontal span on a surface being rasterised.

    The points marked A & B are points on the span, and the surface's plane. 'c' is a camera, with it's field of view (FOV) covering the span.
    One of the key points with perspective correct texture mapping is the z-coordinate of the point on the plane which corresponds to the screen pixel you are working on. If you were to plot these z-values on a graph versus the x-screen-coordinate, the graph is not linear, so, to achieve perspective correct texture mapping, you cannot simply interpolate the z-coordinate, however, you can interpolate 1/z, since a graph of 1/z versus x-screen-coordinate is linear. This allows the z-coordinate of a particular pixel to be calculated with ease.

    The next bit to overcome is how you relate this to the texture. Here is some mathematical proof of various things which will lead up to the answer to this problem:

The plane equation is :


 

Now for some calculus :

    For a plane k and l are constants. This means that graphs of x-coordinate vs z-coordinate and y-coordinate vs z-coordinate both have constant gradients, - the values of k and l respectively. This is proved by the plane equation, lets take dx and dz as an example :

if the value of z is increased by n, then the result of the left hand side of the plane equation increases by nC. To balance this so as to keep the result of the right hand size of the equation unchanged, x must decrease by :

    The above equation is linear, since A and C are constants, - the equation is simple n multiplied by the fraction C/A.
    The same thing holds for dy vs dz, for the same reasons.
    If we are texture mapping triangles, the texture will be mapped onto the plane in a linear fashion. This means that if we were to interpolate in linear fashion along a line on the PLANE, NOT THE SCREEN we could interpolate along the texture in a linear fashion too and obtain the correct result. The result of all this is that :

where u is texture-x, v is texture-y, and z is z-coordinate on plane. texture- x & y are the x & y coodinates on the texture for this particular pixel on the screen.

    As once before, m and n are constants, so the gradients of their respective graphs would be constant too.
    Now we need to turn this information into something useful.

First, lets have some definitions:
    A & B : the coordinates of the beginning and end of the span respectively (3D vectors)
    ta & tb : the texture-coordinates of the beginning and end of the span (2D vectors)
    z : the z-coordinate of the pixel you are currently working on
    u and v : the x- and y- texture-coordinates of the pixel you are currently working on

we know that:
    the beginning of the span has:
        a z-coordinate of a.z,
        a x-texture coordinate of ta.x
        a y-texture coordinate of ta.y
    the end of the span has:
        a z-coordinate of b.z,
        a x-texture coordinate of tb.x
        a y-texture coordinate of tb.y

    As with previous examples, the same rules apply to y-coordinates as to x-coordinates, in respect to z-coordinates, so we only need to take one as an example, - x. If we were to plot the x-texture-coordinate vs the z-coordinate along the span, we would get a graph similar to that below:

    The above graph is basically a straight line graph of the function :

although in this case it is :

    The tangent on the red line (marked out by the light blue) is the span, - it shows the z-coordinates, and the x-texture coordinates of the beginning and end of the span.

    This means that we can calculate the x-texture-coordinate from the above equation using the following :-

    m - the gradient of the above graph
            can be calculated by:

    z - the z-coordinate calculated by the interpolation of 1/z

    c - the u-intercept of the graph above

    To be able to use the above equation, we need to know m and c. The graph can be treated like a normal (x,y) graph, except it is a (z,u) graph. Given the z and u values for the beginning and end of the span, you can calculate the line's gradient and intercept. First for the gradient :

Now for the intercept :

    if we then substitute in values and rearrange:

    The above equations allow us to calculate everything required to calculate the x-texture-coordinate given the following :
    ta & tb : texture coordinates for beginning and end of span (2D vectors)
    a & b : coordinates for the beginning and end of span (3D vectors)
    z : z-coordinate of the pixel you are currently working on.
 

    Now, theres enough there to write code which will do perspective correct texture mapping, - just fill in the blanks to calculate the y-texture-coordinate, and you're there! However, there is a faster method, which I will now outline.  and  can also be linearly interpolated across a span. I shall now prove this.

    If 1/z can be interpolated across the span in linear fashion then it can be calculated from the x-screen-coordinate on the span using a linear equation. Here is the linear equation that will be used :

Lets have some definitions and formulae :

if 

and 

then 

and

    The formula 'v=nz+d' is derived from the previous one, by simply substituting m and c for n and d respectively. v is the y-texture-coordinate, so the procedure for calculating it is the same as that for u, - the x-texture-coordinate, which has already been described.

    We know that for our span, m, n, o, c, d, & e are constant, so :

so:  and 
 

    What this all means is that  and  can be calculated using linear equations; this in turn means that they can be interpolated across a span in linear fashion. Therefore, to do perspective correct texture mapping for a span, you interpolate 1/z (or r), u/z, and v/z, and for each pixel you calculate z (by calculating 1/r), and multiply this z value by the u/z and v/z values for that pixel, and you will have your and v coordinates all ready to look up the texture!

!!**PPHHEEWW**!!
 
 

        If anyone has any questions, ideas for optimiztions, etc, don't hesitate to mail me at :

                mrmeanie@easynet.co.uk
 
 
 
 

 Return to 3D Algorithms Page