Previous | Next --- Slide 25 of 61
Back to Lecture Thumbnails

Some notes on the computational efficiency of evaluating attributes:

  • Plane equations are evaluated once per triangle as a preprocess often referred to as "triangle setup". See details on slide 21
  • Evaluating a plane equation Ax + By + C is two multiply accumulate operations (multiply-add = a x b + c).
  • So for each sample we have to perform one plane equation evaluation (to get 1/w) and a reciprocal (to get w) as per-sample preprocessing.
  • With this preprocessing we can perform perspective-correct evaluation of an attribute's value at a sample point using only three operations (two multiply-adds to evaluate the plane, plus one multiply to scale by w).

Note: modern OpenGL and Direct3D GPU pipelines support up to 32 float4 values. This is 128 scalar attributes per triangle.


I wonder how should I compute w(x,y)? Thx!


@jerry. Perhaps you could compute it from (1/w)(x,y), no?


@kayvon So in this case the 2D-H coordinate w of a screen sample is the depth value z of its original point back in 3D? (So that I can interpolate 1/w from the three 1/z values of the vertices)


After applying the perspective projection transformation point p=[x', y', z', 1], you have the point Mp = [x,y,z,w]. If M is the matrix given on slide 10, then:

 x = x'
 y = y'
 z = z'
 w = -z'

So now consider interpolating attributes a, b, c, etc as well as z across the triangle. Based on what we learned on slide 24, we know that a, b, z, etc. are not affine combinations of screen (x,y) but (a/w), (b/w), (z/w) are:

In other words:

 (a/w)(x,y) = Ax + By + C

So I can compute plane equations for (a/w)(x,y), (b/w)(x,y), etc. using the approach described on slide 21. (In particular, see the detailed comment).

Now imagine there's an additional attribute, who's value is always 1, at each vertex. So I can compute a plane equation for that as well: (1/w)(x,y)

Now when I want to evaluate a(x,y), I know a(x,y) = (a/w)(x,y) / (1/w)(x,y). Done!

Of course, to be efficient and avoid unnecessary divides, at each sample, I would be smart and compute invW = 1 / (1/w)(x,y). And then reuse this value for all attributes:

 a(x,y) = invW * (a/w)(x,y)
 b(x,y) = invW * (b/w)(x,y)
 z(x,y) = invW * (z/w)(x,y)

As I mentioned in my comment at the top of this thread, the cost of a perspective correct interpolation is just 2 multiply-add operations + 1 multiply. Pretty cheap!


@kayvonf Thx! Your illustration about where did 1/w come from: "I can also imagine there's an additional attribute, who's value is always 1 at each vertex." is particularly helpful to me!


@jerrypiglet: Yup, that's exactly how to think about it.


What is 1/w(x, y)?


@pavelkang, can you clarify your question? (I'm a bit unsure what you mean.)

Given a value of an attribute a at each vertex, you can always compute a/w at each vertex (where w is the homogeneous coordinate of the vertex position after applying perspective projection matrix.) Then a/w can be interpolated across the triangle. If a=1, then what you're interpolating is 1/w.


Why are attribute values a linear function of the point's coordinates if we are interpolating across the surface of a triangle in 3D but an affine function of the point's coordinates if we are interpolating across the surface of a triangle in 2D?

If the approach to interpolating attributes using barycentric coordinates in 2D generalizes to 3D where we use the scaled distance between a point on the 3D triangle's plane and an edge of that triangle to get the 3D barycentric coordinates, wouldn't this also be an affine function of the point's x,y,z coordinates?


How do we compute 1/w(x, y)?