Viewport Transformation and Clipping (s/w rendering)

Started by
2 comments, last by MAS 18 years, 11 months ago
Hi All, I’ve been fooling around with software rendering for a few years now, but something occurred to me about the viewport transformation wrt to the depth value. I know there are a few variations on this, but the one I use maps z [-1, 1] to z [0, 1] with: window.z = clip.z * rhw * 0.5 + 0.5 where rhw is 1/w of course. I interpolate 1/z in the rasterizer for the texture mapper, but (and I think you might now what’s coming!) what about the potential for a divide by zero? In my homogenous clipper, I calculate the ‘t’ intersection value with: float t = (-in.z - in.w) / (-in.z + out.z - in.w + out.w). (Although I’m quite sure that an alternative calculation is: float t = -in.z / (out.z - in.z) In the case where the perspective projection matrix maps z to the range[0, 1] er, I digress…) So in calculating 1/z with 1/window.z from above, surely there’s a potential for a divide by zero when a triangle edge intersects with the near frustum plane. I thought about the possibility of an ‘epsilon nudge’ in the viewport transformation to guard against the possible divide by zero, but it’s hacky and I’ve ignored the potential divide by zero before now without and consequences. Has anyone experienced any problems with triangles intersecting the near frustum plane and resulting in a divide by zero? What did you do? Hopefully there are some pixel pushers out there that can put my mind at rest (Nick Capens?!) Cheers, Martin.
Anthony
Advertisement
Hi MAS,

A division by zero is actually impossible when the clipping algorithm is implemented correctly.

The only time you have to calculate 't' is when the vertices are on opposite sides of the (near) clipping plane. This means they have a different 'z' value, so (out.z - in.z) can't be zero and thus there can't be a division by zero.

Although floating-point division by zero doesn't throw an exception (crash your program), it is still advised not to compute 't' before you know the edge is intersected by the clipping plane. I simply do it like this:
float di = V.z;float dj = V[j].z;if(di >= 0){	T[t++] = V;	if(dj < 0)	{		float t = di / (di - dj);		T[t++] = V + t * (V[j] - V);	}}else{	if(dj > 0)	{		float t = dj / (dj - di);		T[t++] = V + t * (V[j] - V);	}}

This way 't' can still be very small, but not zero. By comparing di and dj against a very small number you could prevent numerical instabilities, but I've never experienced a problem with it...
That z value is for clipping.
I believe when you use 1/z for interpolating, textures or what not you use the homogenouse coordinate w. In the perspective matrix transform, w will be equal to z*sin(alpha), alpha = fov. So interpolating that is just like the actual z value of the point.
Hi,

Thanks a lot for your replies.

Cheers,

Martin.
Anthony

This topic is closed to new replies.

Advertisement