How to get an oblique projection matrix?
I want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v.
I looked at the wikipedia and could not understand, those explanation looks very abstract.
Any one can help me to produce a matrix to do it.
The following is not the most general approach, but maybe it gives you enough hints...
I allow an aberration of the LOS (line-of-sight) of the virtual camera (getters not shown):
Using these setters looks e.g. like so:
Then in OpenGL renderer, where the PROJECTION matrix set-up happens, I first generate the usual projection matrix by e.g. using glOrtho, and then consider LOS aberration as follows:
As you can see from use of the indices [8] and [9], the aberrations are considered by offsetting x or y, resp., in dependence of the depth. Due to the surrounding glTranslate()s the offsets are enforced to be zero exactly at the distance of the view plane. So any plane parallel to the view plane and at the distance of viewDistance is left where it is.
I allow an aberration of the LOS (line-of-sight) of the virtual camera (getters not shown):
class Camera {...public: // projection /** sets the mode of projection as specified. */ void setModeOfProjection(Projection::mode_t mode); /** sets the LOS so that it makes the specified \a angleToHorizon and the also specified \a depthShortening. This routine just does a setLOSAberration(float, float, bool), where the arguments are computed to: \code horinzontal = depthShortening * cos(angleToHorizon) vertical = depthShortening * sin(angleToHorizon) \endcode */ void setLOS(angle_t angleToHorizon, float depthShortening); /** resets the LOS to be co-linear with the principal z-axis of this camera's frame. This routine is just a piggy-back on setLOSAberration(float, float, bool) for convenience. */ inline void resetLOS() { setLOSAberration(0.0f, 0.0f); } /** sets the LOS aberration. Normally, the LOS is co-linear to the principal z-axis of this camera's frame, but the camera may also show an aberration here, likely in co-operation with a parallel projection mode, an oblique projection. \post horizontalLOSAberration() == \a horizontal \post verticalLOSAberration() == \a vertical */ virtual void setLOSAberration(float horizontal, float vertical);...};
Using these setters looks e.g. like so:
voidProjection::setToPerspective(Camera& target) { target.setModeOfProjection(PERSPECTIVE); target.resetLOS();}voidProjection::setToOrthographic(Camera& target) { target.setModeOfProjection(PARALLEL); target.resetLOS();}voidProjection::setToCavalier45(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOS(Angle::HALF_PI/2.0f, 1.0f);}voidProjection::setToCavalier30(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOS(Angle::HALF_PI/3.0f, 1.0f);}voidProjection::setToCabinet45(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOS(Angle::HALF_PI/2.0f, 0.5f);}voidProjection::setToCabinet30(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOS(Angle::HALF_PI/3.0f, 0.5f);}voidProjection::setToDimetricTopView(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOSAberration(0.25f, 0.5f);}voidProjection::setToDimetricSideView(Camera& target) { target.setModeOfProjection(PARALLEL); target.setLOSAberration(0.5f, 0.25f);}
Then in OpenGL renderer, where the PROJECTION matrix set-up happens, I first generate the usual projection matrix by e.g. using glOrtho, and then consider LOS aberration as follows:
if(_currentCamera->horizontalLOSAberration() || _currentCamera->verticalLOSAberration()) { float matrix[16]; for(uint32_t i=0; i<16; ++i) { matrix = (i%5==0) ? 1.0f : 0.0f; } const float viewDistance = _currentCamera->viewDistance(); matrix[8] = _currentCamera->horizontalLOSAberration(); matrix[9] = _currentCamera->verticalLOSAberration(); ::glTranslatef(0.0f, 0.0f, viewDistance); ::glMultMatrixf(matrix); ::glTranslatef(0.0f, 0.0f, -viewDistance); }
As you can see from use of the indices [8] and [9], the aberrations are considered by offsetting x or y, resp., in dependence of the depth. Due to the surrounding glTranslate()s the offsets are enforced to be zero exactly at the distance of the view plane. So any plane parallel to the view plane and at the distance of viewDistance is left where it is.
Quote:Original post by chiyuwang
I want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v.
It sounds to me like you might be trying to find the intersection of a ray with a plane. If this is the case, you don't want to search for stuff on projection matrices. Projection matrices are applicable to your problem, but it seems like the hard way to approach it.
Instead, consider that you are sliding your point x in the direction of v. Eventually, you will hit the plane, and this is the point you are trying to find.
Use the parameter t to represent the sliding point like this
Now, you want to find the value of t so that the sliding point lies on the plane.
The condition that the sliding coordinates are lying on the plane is given by
inserting the definition of the sliding coordinates with respect to the parameter t gives
Solving for t gives
NOTE: if the denominator of t is zero, then the sliding point will never come into contact with the plane.
Now, insert this value of t back into the equation of the sliding point to get the actual projected point.
Thank you for your help. I will try it.
Anyway, if I can get a matrix, it will be very easy for me.
This matrix will concatenate with other transformation matrices and transfered into my pixel shader. In my shader it will be just a matrix multiplication.
Anyway, if I can get a matrix, it will be very easy for me.
This matrix will concatenate with other transformation matrices and transfered into my pixel shader. In my shader it will be just a matrix multiplication.
Quote:Original post by Eric_BrownQuote:Original post by chiyuwang
I want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v.
It sounds to me like you might be trying to find the intersection of a ray with a plane. If this is the case, you don't want to search for stuff on projection matrices. Projection matrices are applicable to your problem, but it seems like the hard way to approach it.
Instead, consider that you are sliding your point x in the direction of v. Eventually, you will hit the plane, and this is the point you are trying to find.
Use the parameter t to represent the sliding point like this
Now, you want to find the value of t so that the sliding point lies on the plane.
The condition that the sliding coordinates are lying on the plane is given by
inserting the definition of the sliding coordinates with respect to the parameter t gives
Solving for t gives
NOTE: if the denominator of t is zero, then the sliding point will never come into contact with the plane.
Now, insert this value of t back into the equation of the sliding point to get the actual projected point.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement