# eye and clip coordinates

I’m going through the openGL programming guide, currently in chapter 3 http://www.glprogramming.com/red/chapter03.html about Viewing.

I just had a few questions about what they speak of as the eye and clip coordinates. I think I get it but I just want to be sure. The eye coordinates are the coordinates obtained by multiplying the original coordinates by the modelview matrix. Correct?

I’m not certain about what they refer to as ‘clip coordinates’ though. By my understanding, the eye coordinates are then multiplied by the projection matrix, and the resulting coordinates are clipped to remove any vertices outside the clipping plane. What I’m not sure about is first, is the clipping performed by multiplication of the projection matrix? Or are the vertices clipped before, or after the multiplication? And lastly, which do we call the ‘clip coordinates’, the coordinates that remain after clipping is finished? Or merely the product of the projection matrix?

Yes, that’s correct.

Clipping planes. There are at least six of them, forming the view frustum. But you may also specify additional ones.

A matrix multiplication cannot do the clipping by itself. The multiplication with the projection matrix will merely transform vertices from eye space to clip space. The actual clipping is performed in a separate step.

The later one.

BTW have a look at the OpenGL FAQ (paragraph 9.011 for this topic)

Thanks for the thorough response.

So clip coordinates are simply the result of multiplication by the projection matrix. In that case, when, precisely are they clipped? Is it before or after the perspective division step?

On the one hand, I would say they are clipped “during” the perspective division step. This step takes homogeneous clip space coordinates as input and outputs clipped normalized device coordinates. On the other hand, in order to check whether a vertex is inside the canonical view volume, you need to check the non-homogeneous euclidean coordinates. So you could say the actual clipping happens after perspective division

It doesn’t really matter whether you test
-wc <= [xc, yc, zc] <= wc
or
-1 <= [xd, yd, zd] <= 1

True, but if you want to generate the clipped vertices then you need to intersect the triangle outlines with the faces of the [-1,1]x[-1,1]x[-1,1] volume and find the intersections of the ribs of that volume with the triangle surface. I seriously doubt this is done in homogeneous clip space.

And why do you doubt it? It’s called clip space for a reason.

Because in normalized device coordinates, calculating the intersection of a triangle edge p1/p2 with the y=1 plane is easy:

``````
t = (1-y1)/(y2-y1)
if ( t<0 || t>1)
//no clip
else
clipvertex = p1+t(p2-p1)

``````

try doing that in homogeneous coordinates. There you can’t represent a point along the line as p1+t(p2-p1) unless the homogeneous coordinates are equal. Of course you can do this in homogeneous coordinates, you can write out the equations and see that they are more complex.

It may well be less complex than the special handling you need for wc == 0 (and wc < 0).

You’re right. I forgot about (wc < 0). My assumption that homogeneous could not be represented by p1+t(p2-p1) was wrong. They can. In that case, the only difference is that t is non-linear in euclidean space, but that’s not really an issue if you only need to extract the value of t where it intersects. Clipping to (y=1) then becomes:

``````
p1+t(p2-p1)

where

t = (y1-w1)/((w2-w1)-(y2-y1))

``````

So there are still special cases where you need to avoid division by zero. But like you said, clipping the vertices with (wc < 0 ) should be done in homogeneous space because they will have positive z values after perspective division.

I think you’ll find that in all cases where you would divide by zero you simply don’t need to clip.

But like you said, clipping the vertices with (wc < 0 ) should be done in homogeneous space because they will have positive z values after perspective division.

You can correct for the sign bit after perspective division with a bit of added logic, but the nasty case is wc ~= 0.

Aha. That’s worth checking out.
Thanks 