7

I'm really confused about OpenGL's modelview transformation. I understand all the transformation processes, but when it comes to projection matrix, I'm lost :(

If I have a point P (x, y, z), how can I check to see if this point will be drawn on a clipping volume defined by either by parallel clipping volume or perspective clipping volume? What's the mathematical background behind this process?

genpfault
  • 47,669
  • 9
  • 68
  • 119
Chan
  • 12,569
  • 40
  • 99
  • 152
  • Do you want to learn about the mathematics involved, or do you just want to know how to get an answer? – Jerry Coffin Jun 10 '11 at 02:02
  • @Jerry Coffin: I want to learn the mathematical background too. I googled and found that I can use feedback mode to check, but the paid-off is performance, so I think a mathematical explanation would be more useful. Thank you. – Chan Jun 10 '11 at 02:05
  • 1
    one starting point would be the OpenGL spec. For example, section 2.11 of OpenGL 2.0, which is at: http://www.opengl.org/documentation/specs/version2.0/glspec20.pdf. Despite being part of the specification, this part is largely tutorial, complete with a pretty decent diagram, the exact matrix multiplications used, etc. – Jerry Coffin Jun 10 '11 at 02:16
  • @Jerry Coffin: Great document ;). I will read it now. Thanks a lot. – Chan Jun 10 '11 at 02:22
  • I know it's old, but check this out http://www.crownandcutlass.com/features/technicaldetails/frustum.html – dr4cul4 Jun 17 '15 at 15:16

3 Answers3

13

Apply the model-view-projection matrix to the object, then check if it lies outside the clip coordinate frustum, which is defined by the planes:

    -w < x < w
    -w < y < w
     0 < z < w

So if you have a point p which is a vec3, and a model-view-projection matrix, M, then in GLSL it would look like this:

    bool in_frustum(mat4 M, vec3 p) {
        vec4 Pclip = M * vec4(p, 1.);
        return abs(Pclip.x) < Pclip.w && 
               abs(Pclip.y) < Pclip.w && 
               0 < Pclip.z && 
               Pclip.z < Pclip.w;
    }
Kromster
  • 6,665
  • 7
  • 55
  • 98
Mikola
  • 8,569
  • 1
  • 31
  • 41
  • I'm guessing you test the bounding box using 8 checks for each of the corners? – TheJosh Jan 05 '14 at 10:56
  • @TheJosh There are only 6 checks, since there are only 6 faces on a bounding box. The corners have little to do, since a plane is defined by three points. Roughly, this plugs the coordinate of the point being checked into the plane's equations to verify on which side of the plane it landed according to the sign of the result and the way the planes are defined. Note the abs() trick checks top/bottom planes at once (and left/right too) so only 4 conditions are checked. – NicoBerrogorry Apr 01 '18 at 16:21
  • This fantastic answer is unfortunately obsolete – Paul Childs Nov 19 '19 at 00:46
2

For anyone relying on the accepted answer, it is incorrect (at least in current implementations). OpenGL clips in the z plane the same as the x and y as -w < z < w (https://www.khronos.org/opengl/wiki/Vertex_Post-Processing).

The two tests for z should then be: std::abs(Pclip.z) < Pclip.w

Checking for zero will exclude all the drawn points that are closer to the near field clip plane than the far field clip plane.

Paul Childs
  • 249
  • 2
  • 8
2

To determine if a given point will be visible on the screen, you test it against the viewing frustum. See this frustum culling tutorial:

http://www.lighthouse3d.com/tutorials/view-frustum-culling/

Julio Gorgé
  • 9,998
  • 2
  • 43
  • 60