I'm working on a 3D engine, but I'm stuck on perspective projection. The documentation is a bit confusing. I've got some wireframe objects moving around so far, but I need to add the perspective distortion, as well as move the points so they're relative to the screen's centre, rather than its top/left.
I know how to do this with calculations:
X' = (X*D) / (Z + D)
Y' = (Y*D) / (Z + D)
Then X' = X' + (vWidth/2). and Y' = Y' + (vHeight/2)
Where D is the eye's distance from the front view of the frustum.
I could use the above maths, but I'm assuming that it's quicker to use something in my transformation matrix.
DirectX has a function called Matrix.PerspectiveLH(vWidth, vHeight, D, F), but this messes things up. I think one tutorial said you have to divide the X,Y and Z by the W after you've done the point transformation, but this doesn't work.
Can anyone help me understand this
Thanks - Gary

Perspective projection
Albino
Projection is indeed hard to understand at first,< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
First you have 2 kind of Projections :
Perspective Projection
and
Orthogonal Projection
In 2D you define a Projection to be Orthogonal
In 3D you define a Projection to be Perspective
Most of the time the Z negative is toward you
The more z the more in the back you are
that's why we call it a Z buffer...
The X positive are going right
The Y Positive are getting up
This is by convention but it may be totally different...
LH means Left hand orientation
RH is right hand orientation
This is based on a trick that use your real hand as a tool...
if you extend your right hand palm side down pointing finger in front of you
The direction of your extended finger are the X positive
If you bend your finger down towayd the Y positive axis
you see that your tumb point to the left, so it's the Z positive (right hand axis)
If you do the opposite and use your left hand you'll see that
by using your left hand the Z positif point to the right (the direction of your tumb)
(normally the Left hand rule is what we use)
Now if you talk about centering the view on the center and not top left
it's maybe because you think in 2D
In 2D you set the Ortho Perspective Matrix and then use DXTransform to
set the Projection matrix
This is done by setting -Xmin and +Xmax and then +yMax and -yMin
(a rectangular section on 2d axis X and Y)
It's like the definition of a cartesian plane with 2 axis X and Y
You tell the view what rectangulare section of the cartesian plan you want to see
You can have a screen of 0 to 10 in X and 0 to 10 in Y (positive X right, positive Y up)
(the basic bottom/left are 0,0 view)
You can set -10 to 10 in X and -10 in 10 in Y
(the 0,0 will be in the center of the screen)
As for the Z axis positive in the back (left hand rule...)
(with the left hand ''palm up'' and flat on a table point your finger extended to the right,this point the X positive
when you bend your finger up you get the Y positive,
you see that your tumb point to the back of the screen toward the Z positive...)
The rule is good in 2D (ortho) and 3D (perspective)
In 2D ortho projection 2 same sized cube one at z=0 and one at z=-100 side by side
will appear as the same square...in 2D
In 3D (perpective projection) the same sized cube farther will appear smaller...
Now this was for ''2D''...
For perpective projection the notion of top/left or center is not so important
Your LookAt function that do the VIEW matrix will consider the center of
the screen to be your eyes x,y,z position
It's not in the perspective projection that you decide what your eye position should be
It's more the View matrix
The perspective projection (3D) give you a frustum ("Rectangular Cone")
that is a rectangular box
that begin with your rectangular screen and go in the back to a smaller rectangular shape
(or bigger at the back, I'm not sure)
It's by the View matrix that you move that Rectangular Cone around in 3D
to see your 3D world...Your eye are in the middle of the screen
But with the view matrix (and the lookat function) you can move that Cone
If you want to see your same 2D cube in 3D
You set your View matric (using LookAt) at this position:
Eye=D3DVEctor3(0,0,-10) (z negative are where your eyes are behind the keyboard)
Target to see = D3DVector3(0,0,0)
Up axis=D3DVEctor3(0,1,0)
This way your 0,0,0 will be in the center of the screen where your ''eyes'' lookat
To set your bottom left view you do this in lookat function (to set view matrix)
Eye=D3DVector3(10,10,-10)
Target to see = D3DVector3(10,10,0)
Up axis=D3DVEctor3(0,1,0)
You will have 10,10 as the center of your screen
But the rest is up to the perspective to decide...
You will not have 0,0 for bottom/left view...it depend of the perpective frustum
You define the perspective projection as the frustum view (aspect and Z plane of frustum ''rectangular cone'') (set up the size of the ''flash light cone'' to use)
You use the View projection to set the eye position (by using LookAt function)
(this will move the ''rectangular cone'' around in your world...
like a spot light of a flash light vision in the dark)
You use the World matrix to place object in the scene, this put it in the world
(don't care about anything else when you place object in the scene
the Proj and view matrix do the work)
as for your PerpectiveLH function maybe it would be easier to use another function
that set the matrix then use D3DXTransform to set the View, Proj and World matrix
Set Proj matrix once by Function MatrixPerspective or MatrixOrtho set D3D_PROJ with a D3DTransform that use your matProj
(only have to do this once if your window size stay the same)
Set the ''camera'' with Lookat to create the View matrix (use D3DXTransform set the D3D_VIEW)
(once by scene)
Create a D3DIdentity matrix for the World martix (add translation, multiply to add those matrix)
Set the D3DTranform to set the D3D_World...put your object using only the world matrix set
by the transform
In resume we draw in a World matrix referential, you move that referential around to draw
The perspective matrix define a ''flash light cone''
You move that flash light cone in your world by defining a view matrix
(using where your eyes are placed and where you look at) (using Lookat function)
The only stuff you see of your world is in that cone that you move around
Hoping this can help...
Hari M
Thanks for the reply!
I should have realised I don't need to move each point to the centre of the screen after each point translation.
I'm not using DX3, but I'll look into it.
Thanks - Gary.