Eye-space clipping and affine texture mapping

Toasty

Newcomer
I am developing a software rasterizer and want to be able to support affine (non-perspective correct) texturing but I am encountering a problem in my clipper that I can't seem to solve and I need some help.

I do my near/far plane clipping in projective space with homogenous coordinates. My view volume is defined as [-w <= x,y,z <= w]. I should also mention that my entire transformation pipeline mimicks the behaviour of Open GL 1.1.

My problem is that I cannot find a way to properly interpolate my texture/color coordinates for new vertices created by my clipper for lines & triangles that extend past the near frustum clipping plane and go behind the viewing position. When it comes to perspective-correct texture/color shading everything is fine because I just apply my linear interpolation factor calculated by my clipper to the texture and color coordinates. But for affine texture/color shading my clipper is required to do a hyperbolic interpolation and this is where my meager understanding of 3D is failing me.

I originally developed the following function to find the hyperbolic interpolation factor ftHyper based on the linear interpolation factor:
Code:
float FindHyper_t (PVERTEX pDest, PVERTEX pStart, PVERTEX pEnd, float t)
{
    // pDest is guaranteed to not have w coordinate of 0.0
    return t * (pEnd->position.v[3] / pDest->position.v[3]);
}

This solution works perfectly for left, right, top, bottom, and far frustum plane clipping. But when it comes to near plane clipping and objects that extend behind the viewer, the w coordinate of either the start or end vertex becomes negative and my ftHyper value is no longer correct.

So can anyone please help me with this simple issue? Part of my problem is that I have no books at all on the subject of 3D graphics. I am purely using the internet to do this project (which has gone well up to this point) and I can't find any information about this particular problem. I've also looked at the source code for Mesa and for Klimnt (another solfGL project) but both appear to just do linear interpolation which works only for perspective correct texture/color shading.

Thanks,
-Toasty
 
I don't understand your problem. You say you want to do linear texturing so why not just set your texture W component to a constant 1.0?
 
I need the hyperbolic interpolation because my clipper operates in projective space but for affine mapping I must interpolate texture/color values as if I were in screen space. I can't really explain it any better, so to help clarify things here's some pseudocode about how I perform interpolations in my clipper.
Code:
if (PerspectiveCorrectionHint() == GL_NICEST) {
    InterpolatePosition(pNew, pV1, pV2, t);
    InterpolateNormal(pNew, pV1, pV2, t);
    InterpolateColor(pNew, pV1, pV2, t);
    InterpolateTexcoords(pNew, pV1, pV2, t);
} 
else { // GL_FASTEST , GL_DONT_CARE   
    InterpolatePosition(pNew, pV1, pV2, t);
    InterpolateNormal(pNew, pV1, pV2, t);    
    float ftHyper = FindHyper_t(pNew, pV1, pV2, t);
    InterpolateColor(pNew, pV1, pV2, ftHyper);
    InterpolateTexcoords(pNew, pV1, pV2, ftHyper);
}
 
There is no 'correct' way to clip texture coordinates if you're using them for affine interpolation. I think the best you can do is just plain linear interpolation. Flat polygons (coplanar to the screen) have to look ok, that's the most important.

Have you checked whether the OpenGL specifications say anything about this?
 
Nick said:
There is no 'correct' way to clip texture coordinates if you're using them for affine interpolation. I think the best you can do is just plain linear interpolation. Flat polygons (coplanar to the screen) have to look ok, that's the most important.

Have you checked whether the OpenGL specifications say anything about this?
Strict linear interpolation looks 'okay' if my triangle clips only a single frustum plane. However when clipping against more than one frustum clip plane you can see seams in the texturing because my clipped polygon is decomposed into several triangles and the texture interpolation amounts for each triangle differ.

I checked the OGL 1.3 spec and it only describes linear interpolation for texture and color coordinates while clipping. It doesn't even contain mention of affine texture and color shading so it is certainly possible to just do away with it.

But I'm so close.... I've got interpolation for 5 frustum planes working perfectly. The only thing left to do is figure out how to hyperbolically interpolate the texture/color values for triangles that extend behind the viewer (ie. they contain a vertex or 2 vertices with a -w coordinate).

What's annoying is that my Radeon 9800 Windows OGL driver does not react to a perspective hint of GL_FASTEST - I always get perspective-correct texture and color shading. Does anyone know if there exists an OpenGL implementation (software or hardware) that actually performs affine texture or color shading when requested via PERSPECTIVE_CORRECTION_HINT? Also if someone knows of an old PC game that used affine texturing and whose source code is available please let me know.

Thanks.
 
So you manage to fix the seam problem by using hyperbolic interpolation? That's cool, I never realized that could work. Although...

The problem is that w becomes negative... I'm afraid it's unsolvable. Your interpolation value, t, has to remain between 0 and 1. The way you defined your hyperbolic t, this isn't guaranteed. So even for other clipping planes I think things can go wrong. Could you check that?

Besides, why do you really want to do affine texture mapping? It's ok to speed up rendering of small and distant polygons, but it starts to show serious artifacts for big and closeby polygons. So in situations where in my opinion it is useful, it doesn't clip the near plane anyway...

Tomb Raider 1 used a software renderer where perspective correction could be switched on and off. I think I remember seeing seems. But of course there's not such thing as a 'referece' game for affine texture mapping...
 
Nick said:
So you manage to fix the seam problem by using hyperbolic interpolation? That's cool, I never realized that could work.
Yeah it works, here are some pics:

1. Perspective-correct mapping:
http://www.izabel.info/uploads/p_linear.JPG

2. Affine mapping:
http://www.izabel.info/uploads/p_rational_linear.JPG

3. Affine mapping with near and far planes pushed closer together:
http://www.izabel.info/uploads/p_rational_linear_2.JPG

I'll spend some more time considering solutions to this problem; I don't want to let it go just yet. And I do realize that the result for texturing will look pretty ugly but this technique is still feasible for affine gouraud shading which probably won't look nearly as bad.
 
Toasty said:
3. Affine mapping with near and far planes pushed closer together:
http://www.izabel.info/uploads/p_rational_linear_2.JPG
Is that supposed to be the same polygon? I mean, with the same texture coordinates? It's clearly wrong then, because it doesn't show the full pattern (no red or yellow), and the pattern is not parallel to the polygon (pink at the top, but blue at the bottom). On top of that, there's a seam here as well...
I'll spend some more time considering solutions to this problem; I don't want to let it go just yet. And I do realize that the result for texturing will look pretty ugly but this technique is still feasible for affine gouraud shading which probably won't look nearly as bad.
Well, I certainly applaud trying new things, but it's quite clear to me that this is incorrect. It's not mathematically sound, and visually there are serious problems as well. Sorry. For affine gouraud shading I've always used linear interpolation for clipping.

Anyway, good luck with your project!
 
Nick said:
Toasty said:
3. Affine mapping with near and far planes pushed closer together:
http://www.izabel.info/uploads/p_rational_linear_2.JPG
Is that supposed to be the same polygon? I mean, with the same texture coordinates? It's clearly wrong then, because it doesn't show the full pattern (no red or yellow), and the pattern is not parallel to the polygon (pink at the top, but blue at the bottom). On top of that, there's a seam here as well...
Anyway, good luck with your project!
The purpose of the third image was to demonstrate that my hyperbolic interpolation works with near and far plane clipping in addition to left, right, top, and bottom. To produce the image I moved the near clip plane from 0.1 to ~1.0 and the far clip plane from 12.0 to ~2.5. If you flip between them then you'll see that for every lighted pixel it is exactly the same as the second image. That's the point of my hyperbolic interpolation -- it does not create any new texture seams! :)

The texture seam in the second and third images is produced because the scene is composed of two triangle primitives arranged to look like a square and the texture seam is the expected result for affine texturing.

EDIT -- addendum :

Nick said:
Toasty said:
I'll spend some more time considering solutions to this problem; I don't want to let it go just yet. And I do realize that the result for texturing will look pretty ugly but this technique is still feasible for affine gouraud shading which probably won't look nearly as bad.
Well, I certainly applaud trying new things, but it's quite clear to me that this is incorrect. It's not mathematically sound, and visually there are serious problems as well. Sorry. For affine gouraud shading I've always used linear interpolation for clipping.
I wanted to check what you said, so I started comparing unclipped affine texture-mapped triangles to their clipped versions to see if there is any difference.

Here is a completely unclipped scene (ie. no hyperbolic interpolation taking place):
http://www.izabel.info/uploads/unclipped_affine.JPG

And here is the exact same scene but with left and right frustum clip planes collapsed so as to produce clipping.
http://www.izabel.info/uploads/clipped_affine.JPG

If you flip between them you can see that the hyperbolic interpolation does not alter the texture mapping in any distinct way (there are very slight differences but that may just be jpeg artifacts or caused by slight imprecisions in the calculated clipped vertices). Overall I do think this solution is sound, I just need to devise a special case to work with clipping against a -w coordinate.
 
Thanks for the explanation! Sorry I misunderstood some of it.

Unfortunately, I'm still of the opinion that it doesn't really solve anything. Ok, there are no new seams, but that's not something to care much about anyway. For gouraud shading, you're not going to see the seams, and it's actually more correct to use the linearly interpolated clipping points. Even if it causes more seams, they will be less noticable.
I wanted to check what you said, so I started comparing unclipped affine texture-mapped triangles to their clipped versions to see if there is any difference.
...
Could you post those as .png files? Preferably a scene where the polygon is a bit more tilted. I'm a bit too lazy to work out the exact math, I'd rather verify things experimentally. ;)

It's something weird you're doing here. You attempt to fix a wrong interpolation with another wrong interpolation. The common way is to use hyperbolic interpolation in screen space and linear interpolation in clip space. What you do is linear interpolation in screen space and hyperbolic interpolation in clip space. Unfortunately, two wrongs almost never make a right. But it's a cool attempt. 8)
 
Useless tidbit of info: at work I have a PC with a Matrox G450... In OpenGL it screws up lighting when a polygon is clipped against the viewing frustum.
I suppose it's because it does linear gouraud shading, and the clipper is also bugged.
 
Toasty said:
Nick said:
There is no 'correct' way to clip texture coordinates if you're using them for affine interpolation. I think the best you can do is just plain linear interpolation. Flat polygons (coplanar to the screen) have to look ok, that's the most important.

Have you checked whether the OpenGL specifications say anything about this?
Strict linear interpolation looks 'okay' if my triangle clips only a single frustum plane. However when clipping against more than one frustum clip plane you can see seams in the texturing because my clipped polygon is decomposed into several triangles and the texture interpolation amounts for each triangle differ.
Then you must be doing something else incorrectly.

If you have your points in eye/camera space AKA cannonical clipping coordinates, then you are still in homogenous space, i.e. you have [X,Y,Z,W] positions, and all clipping is linear.
 
Back
Top