I have extracted the frustum planes from a perspective matrix with some help from this homepage.
Can I use the same equations for an orthographic matrix?
************************UPDATED************************
I'm using cascaded shadow mapping(CSM) with 4 cascades and need therefore cull objects in different cascades from the lights perspective. It would be quite expensive to calculate the 6 frustum planes with this method:
Fore each cascade:
Calculate the inverse matrix from the finalMatrix = lightOrthoMatrix * lightViewMatrix.
Use the inverse final matrix and multiply it with the 8 frustum NDC corners to get the final frustum corners in world space.
Use these corners to finally calculate the 6 frustum planes.
I discovered today that you can use the same "cheap" method to calculate the 6 frustum planes by extracting them from the final matrix. See this homepage. It doesn't matter if we use Perspective Projection or Orthographic Projection.
Related
I'm projecting 3D points with X,Y,Z model coordinates to X,Y image coordinates using a 4x4 perspective view-projection matrix. There is only one model, so it is like a MVP matrix where the M matrix is unity.
Is it possible to extract the coordinates of the position (in model coordinates) of the camera from the view-projection matrix. (i.e. the translation component of the view-matrix)?
Also, what exactly is the meaning of the Z-component in the projected image coordinates (after division by W)? I know it is between -1 and 1 for points between the near and far planes, but is it possible to deduce the distance of the point to the camera (in model coordinates) from it?
I am having profound issues regarding understanding the transformations involved in VTK. OpenGL has fairly good documentation and I was of the impression that VTK is verym similar to OpenGL (it is, in many ways). But when it comes to transformations, it seems to be an entirely different story.
This is a good OpenGL documentation about transforms involved:
http://www.songho.ca/opengl/gl_transform.html
The perspective projection matrix in OpenGL is:
I wanted to see if this formula applied in VTK will give me the projection matrix of VTK (by cross-checking with VTK projection matrix).
Relevant Camera and Renderer Parameters:
camera->SetPosition(0,0,20);
camera->SetFocalPoint(0,0,0);
double crSet[2] = {10, 1000};
renderer->GetActiveCamera()->SetClippingRange(crSet);
double windowSize[2];
renderWindow->SetSize(1280,720);
renderWindowInteractor->GetSize(windowSize);
proj = renderer->GetActiveCamera()->GetProjectionTransformMatrix(windowSize[0]/windowSize[1], crSet[0], crSet[1]);
The projection transform matrix I got for this configuration is:
The (3,3) and (3,4) values of the projection matrix (lets say it is indexed 1 to 4 for rows and columns) should be - (f+n)/(f-n) and -2*f*n/(f-n) respectively. In my VTK camera settings, the nearz is 10 and farz is 1000 and hence I should get -1.020 and -20.20 respectively in the (3,3) and (3,4) locations of the matrix. But it is -1010 and -10000.
I have changed my clipping range values to see the changes and the (3,3) position is always nearz+farz which makes no sense to me. Also, it would be great if someone can explain why it is 3.7320 in the (1,1) and (2,2) positions. And this value DOES NOT change when I change the window size of the renderer window. Quite perplexing to me.
I see in VTKCamera class reference that GetProjectionTransformMatrix() returns the transformation matrix that maps from camera coordinates to viewport coordinates.
VTK Camera Class Reference
This is a nice depiction of the transforms involved in OpenGL rendering:
OpenGL Projection Matrix is the matrix that maps from eye coordinates to clip coordinates. It is beyond doubt that eye coordinates in OpenGL is the same as camera coordinates in VTK. But is the clip coordinates in OpenGL same as viewport coordinates of VTK?
My aim is to simulate a real webcam camera (already calibrated) in VTK to render a 3D model.
Well, the documentation you linked to actually explains this (emphasis mine):
vtkCamera::GetProjectionTransformMatrix:
Return the projection transform matrix, which converts from camera
coordinates to viewport coordinates. This method computes the aspect,
nearz and farz, then calls the more specific signature of
GetCompositeProjectionTransformMatrix
with:
vtkCamera::GetCompositeProjectionTransformMatrix:
Return the concatenation of the ViewTransform and the
ProjectionTransform. This transform will convert world coordinates to
viewport coordinates. The 'aspect' is the width/height for the
viewport, and the nearz and farz are the Z-buffer values that map to
the near and far clipping planes. The viewport coordinates of a point located inside the frustum are in the range
([-1,+1],[-1,+1], [nearz,farz]).
Note that this neither matches OpenGL's window space nor normalized device space. If find the term "viewport coordinates" for this aa poor choice, but be it as it may. What bugs me more with this is that the matrix actually does not transform to that "viewport space", but to some clip-space equivalent. Only after the perspective divide, the coordinates will be in the range as given for the above definition of the "viewport space".
But is the clip coordinates in OpenGL same as viewport coordinates of
VTK?
So that answer is a clear no. But it is close. Basically, that projection matrix is just a scaled and shiftet along the z dimension, and it is easy to convert between those two. Basically, you can simply take znear and zfar out of VTK's matrix, and put it into that OpenGL projection matrix formula you linked above, replacing just those two matrix elements.
i've been drawing directly into homogenous clip space (the 2x2x2 cube centered around 0,0,0) in opengl and i've realized that the perspective transformation matrix transforms all geometry from one right-parallelipid (view-space) to another right-parallelipid (homogenous clip-space).
so, why the heck does every opengl article use a non-right-parallelipid frustum to illustrate how projection works? i understand that the perspective transformation matrix will cause everything to get scaled by a term containing its distance from the camera and the camera's distance from the plane... is the traditional frustum illustration trying to explain that? or are we truly entered some warped space at some point in the perspective transformation? if so, how are we ending up back at a right-parallelipid (homogenous clip-space) at the end of it all?
You are right in the sense that there is just some affine, linear transformation and no real perspective distortion - when you just interpret the clip space as a 4-dimensional vector space.
But the clip space is not the "end of it all". The perspective effect is a nonlinear transformation which is finally achieved by the perspective division which will be done after the transformation to clip space. The projection matrix determines the w value that will be the divisor for this, and which is typically just -z_eye.
I want to draw a frustum using GL_LINE_STRIP. What will be my coordinates for these frustum vertices? I have model view and projection matrices. Is it possible to calculate coordinates in shader itself using these matrices?
If you want the world space coordinates for the frustum corners, all you need to do is project the 8 corner points from NDC space (which is going from -1 to 1 in every dimension, so the corner points are easy to enumerate) back to world space. But do not forget that you have to divide by w:
c_world = inverse(projection * view) * vec4(c_ncd, 1);
c_world = c_world*1.0/c_world.w;
While I wrote this in GLSL syntax, this is meant as pseudocode only. You can do it in the shader, but that means that this has to be calculated many times (depending on which shader stage you put this into). It is typically much faster to at least pre-calculate that inverted matrix on the CPU.
I would like to know if it is possible to build a 3D square frustum by applying some kind of tranformation to glutSolidCube(GLDouble size). I am guessing some kind of shear matrix is involved, which - from what I can tell - is not a built-in transformation.
Note, I don't care at all about the viewing frustum (which, as you might imagine, is making any Google searches skewed). I'd simply like to have a 3D square frustum as part of my scene. Any ideas on how to produce one from a cube would be appreciated!
It is not shear matrix, it is a projection matrix for perspective projection. You multiply the coordinates of unit cube's vertices by inverse projection matrix to get the coordinates of frustum vertices. To get the frustum's coords in world space you also need to multiple the vertices by the inverse Camera matrix (view matrix).
Look here for detailed formulae: http://www.songho.ca/opengl/gl_projectionmatrix.html
To deform the cube it is better to create the VBO with desired vertices or just render a number of deformed quads, if you want some quick'n'dirty implementation using the fixed-function pipeline.
P.S.
There's a code extract to calculate the corners of the frustum: http://www.gamedev.net/topic/606716-frustum-corners-from-view-projection/
Yes it is possible to transform your cube into a frustum given a very projection matrix. First define a focal distance d that is the point where the edge of the frustum are converging. Then multiply all the corners of your volume by this matrix:
P = [ 1 0 0 0
0 1 0 0
0 1 1/d 0
0 0 1 0 ]