• Create Account

# World Space Camera Frustum?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

4 replies to this topic

### #1uglybdavis  Members   -  Reputation: 764

Like
0Likes
Like

Posted 12 December 2013 - 12:22 AM

I posted something similar in the OpenGL section of the forum, but i feel this question is different enough to ask here.

I'm trying to get my head around Frustum Transforms. I'm trying to render a frustum in it's correct world space, then cull other world space objects by that frustum. So, i make a frustum, and position my camera at (0.0, 7.0, 0.0). The cameraView is the inverse of the cameras position matrix.

First, lets make sure the frustum looks correct without any transformation applied:

glm::mat4 viewProjMatrix = cameraProjection;
Frustum worldFrustum = ExtractFrustum(viewProjMatrix);
This is rendered in red and is correct.

Next, i try to extract the frustum planes from the ViewProjection (projection * view) matrix:

glm::mat4 viewProjMatrix = cameraProjection * cameraView;
Frustum worldFrustum = ExtractFrustum(viewProjMatrix);
The result of this is rendered in green. I have no words for how wrong that is.

So, lets brute-force this. Get the world corners of the frustum, then multiply them by the camera transform:

glm::mat4 viewProjMatrix = cameraProjection;
Frustum worldFrustum = ExtractFrustum(viewProjMatrix);
std::vector<glm::vec3> corners = GetWorldCorners(worldFrustum);
for (int i = 0, size = corners.size(); i < size; ++i) {
glm::vec4 vertex = cameraWorldPos * glm::vec4(corners[i], 1.0f);
corners[i] = glm::vec3(vertex.x, vertex.y, vertex.z);
}
The result is rendered in blue. This frustum renders in a perfect position, exactly where i'd expect the green one to render.

Now, the big question. All the articles i read about frustum culling say in order to extract the frustum in world space i simply need to extract the frustum from the ViewProjection matrix. As the above rendering shows this is incorrect. Am i missing something here?

My source code:    http://pastebin.com/UtFnvGAt

All help is appreciated.

### #2Ohforf sake  Members   -  Reputation: 937

Like
1Likes
Like

Posted 12 December 2013 - 05:07 AM

I assume, that the fault is in the ExtractFrustum function and not with the projection view matrix.
For reference, try this:
std::vector<glm::vec3> GetWorldCornersFromMatrix(const glm::mat4& projectionView) {
gkm::mat4 inverseProjectionMatrix = glm::inverse(projectionView);

std::vector<glm::vec3> corners; corners.reserve(8);
for (unsigned x = 0; x < 2; x++)
for (unsigned y = 0; y < 2; y++)
for (unsigned z = 0; z < 2; z++) { // I might mess up the order of the frustrum corners here. But the position should be correct
glm::vec4 projClipSpacePosition(x*2.0f-1.0f, y*2.0f-1.0f, z*2.0f-1.0f, 1.0f);
glm::vec4 projWorldSpacePosition = inverseProjectionMatrix * projClipSpacePosition;
corners.push_back(glm::vec3(projWorldSpacePosition.x / projWorldSpacePosition.w,
projWorldSpacePosition.y / projWorldSpacePosition.w,
projWorldSpacePosition.z / projWorldSpacePosition.w);
}
return corners;
}

If the above function produces the expected points, can you verify that the planes from ExtractFrustum are correct?

### #3uglybdavis  Members   -  Reputation: 764

Like
0Likes
Like

Posted 12 December 2013 - 02:35 PM

void RenderFrustumYellow() {
glm::mat4 cameraWorldPos = glm::translate(0.0f, 7.0f, 0.0f);
glm::mat4 cameraProjection = glm::perspective(60.0f, 0.9235993f, 1.0f, 5.0f);
glm::mat4 cameraView = cameraWorldPos._inverse();

glm::mat4 viewProjMatrix = cameraProjection * cameraView;
glColor3f(1.0f, 1.0f, 0.0f);
RenderFrustum(GetWorldCorners(viewProjMatrix));
}


Renders the image in the same spot as the green frustum in the first screenshot.

Updated source: http://pastebin.com/RuwDFfmp

If extract frustum works fine for an untransformed frustum, i'm not sure why it would not work on a transformed one. Of course i am assuming that the memory layout of glm::value_ptr matches the memory layout of glGetFloatv( GL_MODELVIEW_MATRIX, modl );

I'll check that assumption later when i get home and have some more time.

Edit: Thinking a bit on that, if glMultMatrixf works with glm::value_ptr then the memory layout is of course the same as glGetFloatv.So, i'm just as clueless as ever....

Edited by uglybdavis, 12 December 2013 - 02:51 PM.

### #4Ohforf sake  Members   -  Reputation: 937

Like
1Likes
Like

Posted 13 December 2013 - 01:39 AM

void RenderFrustumYellow() {
//snip
}

Renders the image in the same spot as the green frustum in the first screenshot.

That's strange. That would indicate, that the projection view matrix is already broken.
What exactly does glm::mat4::_inverse do? According to a quick search, glm::inverse seems to be the glm function for matrix inversion. I can't find anything on _inverse.
Also, can you post the values of viewProjMatrix for the above example?

### #5uglybdavis  Members   -  Reputation: 764

Like
0Likes
Like

Posted 13 December 2013 - 02:23 AM

I took a quick look trough _inverse, and at a cursury glance it looks like the code divides the matrices transpose by it's determinant.

Anywhom, i tested the code with glm::inverse, and it works! I feel kind of dumb for not checking that first.

Thank you so much for the time and effort! You have no idea how much you helped me out right there!

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS