0
\$\begingroup\$

I'm working on a 3D game where I sometimes want to display only a cross-section of the scene. Ideally I would like this to be just the intersections of the scene with a plane. But the only way I've been able to achieve this so far is by setting the near and far culling planes to be very close together. However, there are two problems with this approach:

  1. The result isn't actually 2D, the cross-sections have the thickness the size of the gap between the culling planes (this isn't a huge deal, but would be nice to fix)
  2. Most objects become quasi-outlines since their fronts and backs are now culled by the camera. I at least want this to be filled in (e.g. for a sphere I want a solid circle instead of just an outline).

Is there a way to make a very small gap between the near and far culling planes but filling in the interior of the objects, or is there another way to achieve this plane-intersection effect?

\$\endgroup\$
1
\$\begingroup\$

Yes, I think there are a few ways you could do this

To start, to address your depth problem, you’ll want to use an Isometric Projection matrix, instead of the typical Perspective Projection matrix (which creates that frustum). Pretty straight forward, for the most part. Makes a cube look like a square when looking directly at any face head-on. I recommend taking a peek at this wikipedia article to see what other options are out there.

As for the cross section, there are a few options. I’m not great with graphics, but I do know about the OpenGL discard statement which would allow you to simply check the depth before rendering the fragment, however you will incur a notable performance hit by calling discard. According to this question you could simply adjust the projection matrix far plane every time the fragment is above whatever depth you designate.

Apart from all that shader stuff, if you’re just looking for a way to slice all of your meshes with a plane, i would be remiss to not mention the Sutherland-Hodgman Clipping Algorithm. It achieves precisely what you described, and it is still used in certain contexts today because it’s quick, it preserves shapes and winding order, and it’s very simple to implement and understand. If you google it, there’s lots of examples and youtube videos.

\$\endgroup\$
4
  • \$\begingroup\$ The mention of Sutherland-Hodgman sent me down the right path I think. I was already using an orthographic/orthogonal projection, but I was hesitant to try to do this calculation myself until I saw the pseudo-code for Sutherland-Hodgman. It's possible there's a better way to handle it but I was able to use similar methods to at least compute the plane intersection (i.e. not the interior of the cross-section but the boundary) and then sort those into clockwise order to draw a polygon. It was a bit tricky but it's working, so thank you! \$\endgroup\$ Jan 27 '21 at 1:49
  • \$\begingroup\$ Glad to hear :) I originally was going to simply recommend the sutherland hodgman algorithm as it is what i would have done, but that is primarily because it is used in physics narrowphase collision detection for fast clipping. I figured i would present some other options as well but i am glad to hear that it worked for you :) \$\endgroup\$
    – Jon
    Jan 27 '21 at 1:51
  • \$\begingroup\$ @thesquaregroot I should mention that I believe a correct implementation should not require the use of sorting, however, if it gets the job done then all is well \$\endgroup\$
    – Jon
    Jan 27 '21 at 1:53
  • \$\begingroup\$ Well, after looking into things more it seems like Sutherland-Hodgman isn't as easily translated into 3D as I was trying to make it. I was able to make it work decently well for certain convex shapes (the vast majority of what I'm working with), especially since I only wanted to keep the clipped section of each object, but it would take some more work for a more general solution. Not 100% sure what I'll do from here, but at least I've got something that's good enough for the time-being. Thanks again! \$\endgroup\$ Jan 27 '21 at 4:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .