0
\$\begingroup\$

I understand to extract clip planes from the perspective matrix one can follow the methodology laid out by Gribb-Hartman as documented here:

http://www.cs.otago.ac.nz/postgrads/alexis/planeExtraction.pdf

However, I have noted that, given a perspective transformation matrix, such as the one provided by glm::perspective, you will get you planes in the form of the general plane equation ax+by+cz+d in view space.

Yet, as far as I am aware that once the 4D co-ordinates of a vertex, (where w == 1), are multiplied by a perspective matrix, they are considered to be in clip space, prior to their division by 'W' to bring them in to Normalized Device Coordinates form (NDC).

I understand that testing whether to clip a vertex or point in clip space is easy enough, as if the following inequalities are met, the vertex should not be clipped.

Clip planes for extraction

If this is the case, why do we ever need to extract the planes to be in view space?

Additionally if we consider the line P->Q and lets assume:

P is inside the viewing frustum

Q is outside the viewing frustum

we will need to generate a new vertex with point R which resides on the line P->Q but it needs to exist on the intersecting plane.

Line plane intersection

If the planes we extract using Gribb-Hartmann are in view space, how can we create the vertex R in clip space? As I can see as the extracted planes exist in view space, it would be logical to test the line P->Q in view space for the intersection and produce the vertex R and them remove Q from out buffer. So why is clip space not just cliping space?

I am very confused

Thanks for any insight.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I'm a bit confused by your question. Your title asks "why clip in clip space", but you seem to be asking "why clip in view space", noting how much more complicated it is than doing the same operation in clip space. So, that seems to lead to a simple answer: "don't clip polygons in view space, clip polygons in clip space, that's what it's good at". We might use frustum planes in different spaces for other purposes, like culling the set of objects to light/render, but generally not for polygon clipping. Where have I missed what you're asking about? \$\endgroup\$
    – DMGregory
    Dec 3 '21 at 1:02
  • \$\begingroup\$ I see. I guess in hindsight is my main source of confusion/question is that when we extract clip planes using Gribb-Hartmann we end up with a normal and offset in view space. How do we get the frustum clipping plane, that we create new vertices against in clip space? \$\endgroup\$ Dec 3 '21 at 9:36
  • \$\begingroup\$ In clip space, the frustum planes are just the sides of a unit cube, so we don't need to "get" them. They're constants known a priori. The projection matrix is designed to map the arbitrary frustum in view space into this standard shape in clip space, so that the clipping code downstream just needs to do simple checks like x > 1, x < -1 etc \$\endgroup\$
    – DMGregory
    Dec 3 '21 at 12:40
  • \$\begingroup\$ Yeah. That occurred to me overnight. Thanks for the clear explanation. I was thinking clip space was a volume where the planes need to be found, not a unit cube. \$\endgroup\$ Dec 3 '21 at 13:16
0
\$\begingroup\$

TL;DR;

  • Clipping is one form of culling, and it is best done in GPU. But there are other forms of culling, some of which we do in CPU. Which are useful, because they mean sending less polygons to the GPU. And thus, calling the clip space culling space would not be accurate.
  • And there are other uses for those planes aside from clipping. Including but not limited to frustum culling. However cutting triangles by creating vertex in the intersection with a plane is not the common case today.

Why do we need to extract the planes?

why do we ever need to extract the planes to be in view space?

There are multiple reasons to extract the planes. And, yes frustum culling would be one reason. It usually involves discarding meshes in CPU before sending them to the GPU.

We can use the same approach described in the linked document to extract planes in whatever space we need, it is matter of which matrices we use. And usually we want the planes in world space. But why extract them in the view space in particular? I don't know. But we can!

I suppose you got the idea in the same place you got the idea of cutting triangles with the planes by inserting vertex. But I'm here to tell you to don't do that.


Why is the clip space called like that?

So why is clip space not just culling space?

Here I'm interpreting this question as if it were asking about the name "clip space".

Clipping is a type of culling, but not the only one. The other common culling operations are backface culling, occlusion culling and frustum culling. There are others, for example normal culling is basically backface culling but done in CPU before sending the data to the GPU. Which is not entirely disimilar to how frustum culling is basically clipping except done in CPU before sending the data to the GPU.


Why do we cull before sending the data to the GPU?

We cull in CPU because that way we send less data to the GPU. Sometimes too many vertex become the bottle neck and have a real impact on performance. For a good while polygon count was on the top of the list of performance concerns, and still is, depending who you ask. So we will use levels of detail (using meshes with less vertex when they are far away from the camera), and we will do all sort of culling.


What does frustum culling mean anyway?

I assure you that when people complain that a game engine does not do frustum culling, the GPU is still clipping, but the complaint is not about nothing.

By frustum culling we might mean to not send meshes that we can be certain to be outside of view (Or even to discard individual faces depending on the position of the camera, as some games do). Doing this is important for open world games where there is plenty of geometry in every direction.

You would, of course, combine this some form of space partitioning. Due to the fact that discarding an entire partition is better than discarding individual meshes.

For games set in interiors, you can use an hybrid portal based occlusion and frustum culling (where portal means door or window or similar). Which is done by first finding what portals are in the viewing frustum. And then figuring out what rooms they connect to, and find portals in them. Except you are going to clip the viewing frustum to the portal (so you have a smaller - skewed, not centered - viewing frustum that represents the view through the portal), and use that to find if there are any portals in view in the other room. And so on. Of course, for each room you can do frustum culling, not with the original viewing frustum but with the frustum(s) after clipping through the portal(s) that lead to that room.

Also, by frustum culling, if you dig enough - or you are looking at some old documentation - you will find the technique of cutting triangles by adding vertex in the intersection with the planes, so that we only send the pieces that are inside the viewing frustum to the GPU. This was absolutely worth doing back in the day of immediate mode rendering and render lists. I'm not convinced it is worth doing today.

However, here is something similar - from my own experience - that I needed those planes for: to generate meshes based on the viewing frustum (instead of cutting them). In particular, I wanted an "infinite" plane. No, I can't put vertex at infinity and then cut the mesh to the viewing frustum. But I can extract the planes of the viewing frustum, compute where they intersect the plane I want, and that tells me where to put the vertex to represent it. Similarly when I want "infinite" lines, I can follow the same approach. I also needed this to work in orthographic and perspective projections.


Why don't we project meshes to clip space in CPU and do frustum culling that way?

So why is clip space not just culling space?

Here I'm interpreting this question as if it were asking about where to do clipping operations.

The GPU is faster doing that. So, clip polygons in clip space in the GPU, where it is faster.

However, as I was saying, polygon count is important. We want to do something in the CPU that is faster. That something is frustum culling.

Plus, be aware that we might be doing frustum culling by a different frustums (such as I described above when talking about portals). And I also want to mention that not every rendering technique uses meshes (e.g. ray casting/marching).


How can frustum culling in the CPU be faster than clipping in the GPU?

If we are going to do this in CPU we are going to take shortcuts. For instance, if we define a sphere that is guaranteed to contain a mesh and we find that the sphere is entirely outside of the viewing frustum, then we are certain the whole mesh is outside the viewing frustum.

Similarly we could use AABB or OBB instead of spheres. In fact, if you have space partitioning, chances are the partition is an AABB (either you are using an oct-tree or chunks or similar), and if it is entirely outside the viewing frustum, any mesh entirely inside the partition is outside the viewing frustum.

You might also be interested in bounding volume hierarchies.

By the way, assuming we are working with a perspective projection: You can test against the viewing line with the dot product (of the viewing direction and the direction from the camera to the point being tested). It is a coarse test, and you need to compute the threshold for the dot product depending on the the vertical and horizontal viewing angle with trigonometry - thankfully viewing angle does not change often. A more refined alternative is to make an horizontal test and a vertical test. And that is another way to define the planes. However, it only works on a - centered, not skewed - perspective projection.

As you can see, we can discard who knows how many vertex in a few checks in CPU.

\$\endgroup\$
4
  • \$\begingroup\$ So why is clip space not just culling space? <-- this was a typo by me sorry. As for the answer this is very helpful. \$\endgroup\$ Dec 3 '21 at 9:44
  • \$\begingroup\$ My follow on question, is that this has all arisen from a software rasterizer I am writing to mimic the common graphics API's under the hood so to speak. I am wondering if we extract clip planes from the perspective matrix, and they end up being in view space. How do we get them to be in clip space, so we can generate the new clip vertices there? \$\endgroup\$ Dec 3 '21 at 9:46
  • \$\begingroup\$ @HumilityDev In NDC the planes would be trivial, since there the viewing volume is not a frustum anymore. If we have [-1,1] after dividing by w we would be checking -1 < x/w < 1, if we need to check before dividing by w it would be: -w < x < w. That is w+x > 0 && w-x > 0. I found a document that explains further: Clipping Using Homogeneous Coordinates. \$\endgroup\$
    – Theraot
    Dec 3 '21 at 10:45
  • \$\begingroup\$ Never mind I miss understood the literature about clip space and where the w value came from. I mistakenly always assumed it was 1 not factoring in the fact the perspective matrix will alter the w value. Many thanks. \$\endgroup\$ Dec 3 '21 at 10:46

You must log in to answer this question.

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