Advertisement Jump to content
Sign in to follow this  
uglybdavis

OpenGL World Space Camera Frustum?

This topic is 1862 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

 

OT9hiM.png

 

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.

 

Share this post


Link to post
Share on other sites
Advertisement
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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!