Sign in to follow this  

Viewport Transformation and Clipping (s/w rendering)

This topic is 4592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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[i].z;
float dj = V[j].z;

if(di >= 0)
{
T[t++] = V[i];

if(dj < 0)
{
float t = di / (di - dj);
T[t++] = V[i] + t * (V[j] - V[i]);
}
}
else
{
if(dj > 0)
{
float t = dj / (dj - di);
T[t++] = V[i] + t * (V[j] - V[i]);
}
}


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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this