views:

54

answers:

2

Hi All,

So I'm writing my own custom 3D transformation pipeline in order to gain a better understanding of how it all works. I can get everything rendering to the screen properly and I'm now about to go back and look at clipping.

From my understanding, I should be clipping a vertex point if the x or y value after the perspective divide is outside the bounds of [-1, 1] and in my case if the z value is outside the bounds of [0, 1].

When i implement that however, my z value is always -1.xxxxxxxxxxx where xxxxxxx is a very small number.

This is a bit long, and I apologize, but I wanted to make sure I gave all the information I could.

First conventions:

I'm using a left-handed system where a Matrix looks like this:

[m00, m01, m02, m03]
[m10, m11, m12, m13]
[m20, m21, m22, m23]
[m30, m31, m32, m33]

And my vectors are columns looking like this:

[x]
[y]
[z]
[w]

My camera is set up with:

A vertical FOV in radians of PI/4.

An aspect ration of 1. (Square view port)

A near clip value of 1.

A far clip value of 1000.

An initial world x position of 0.

An initial world y position of 0.

An initial world z position of -500.

The camera is looking down the position Z axis (0, 0, 1)

Given a vertex, the pipeline works like this:

Step 1: Multiply the vertex by the camera matrix.

Step 2: Multiply the vertex by the projection matrix.

Projection matrix is:

[2.41421, 0,       0,         0]
[0        2.41421, 0,         0]
[0,       0,       1.001001,  1]
[0,       0,       -1.001001, 0]

Step 3: Multiply the x, y and z components by 1/w.

Step 4: [This is where the problem is] Clip the vertex if outside bounds.

Step 5: Convert to screen coordinates.

An example vertex that I have is

(-100, -100, 0, 1)

After multiplying by the camera matrix i get:

(-100, -100, 500, 1)

Which makes sense because relative to the camera, that vertex is 100 units to the left and down and 500 units ahead. It is also between the near clip of 1 and the far clip of 1000. W is still 1.

After multiplying by the projection matrix i get:

(-241.42135, -241.42135, 601.600600, -600.600600)

This I'm not sure if it makes sense. The x and y seem to be correct, but i'm iffy about the z and w since the next step of perspective divide is odd.

After the perspective divide I get:

(0.401966, 0.401966, -1.001665, 1)

Again the x and y make sense, they are both within the bounds of [-1, 1]. But the z value is clearly outside the bounds even though i believe it should still be within the frustrum. W is back to 1 which again makes sense.

Again apologies for the novel, but I'm hoping someone can help me figure out what I'm doing incorrectly.

Thanks!

+1  A: 
e.James
Hmmn, ok I guess that makes sense since the rendering is still correct. But do i not need that z value to store in my depth buffer? And if i am storing it, does it not need to be between the bounds of [0, 1] or at least [-1, 1]?
Jon
Have a look at http://www.gamedev.net/community/forums/topic.asp?topic_id=483363. I think you may have to do the clipping *before* dividing by w. In that case, you could calculate the z buffer value in the clipping algorithm, where it would be simply be z/1500 (in your example).
e.James
Here's another one: http://www.codermind.com/articles/Depth-buffer-tutorial.html
e.James
Please disregard my previous two comments, and see the update I posted.
e.James
Ok cool, so i tried that and still no dice. Which makes sense because 0 isn't outside my depth range because the range is relative to the camera, not in absolute terms. However I did manage to solve it and I'll respond below with the answer.
Jon
+1  A: 

Ok, it looks like I figured out what the problem it was.

My projection matrix was:

[2.41421, 0,       0,         0]
[0        2.41421, 0,         0]
[0,       0,       1.001001,  1]
[0,       0,       -1.001001, 0]

But it really should be transposed and be:

[2.41421, 0,       0,         0]
[0        2.41421, 0,         0]
[0,       0,       1.001001,  -1.001001]
[0,       0,       1,         0]

When using this matrix, my x and y values stay the same as expected and now my z values are constrained to be within [0, 1] and only exceed that range if they are outside the near of far clip plane.

The only issue now is that I'm quite confused as to whether I'm using a right or left handed system.

All i know is that now it works...

Jon
Good stuff. I'm glad to hear you got it figured out `:)`
e.James
Thanks for your help though, i definitely appreciate it.
Jon