Understanding clippingPlanes

Hi,

I have some problems understanding exactly how clipping planes work, both positioning and making them actually do what I want to.

Preface/goal
It is important to note that I use a custom terrain provider.

I have an underground geometry. The geometry touches the surface of the terrain and exists below. Imagine it as trench. I want to clip through the terrain at the top of this geometry. It is currently an entity of type polylineVolume because it supports custom shapes (Trapezoid). This entity is not included in the Sandcastle example, only it’s coordinates.

The attempt
I have tried constructing two parallel lines from the original path. The distance between these lines are 0.5 of the trapezoid top width on each side of the original path. Then I extract the coordinates to form a rectangle/polygon. These coordinates serves as a basis for the clipping planes, and is the area I want to clip. I calculate a midpoint and vectors to position the planes.

I use a Plane for each clippingPlane to visualize the position, as I haven’t been able to find a way to visualize clipping planes properly. This can be seen in the Sandcastle example below.

The ultimate goal here is to make the terrain clip between the lines seen in the provided Sandcastle link.

The problem

  1. I can’t make the clipping planes work. There is no clipping at all. They are constructed from the same values as the panes, and they should overlap which after my understanding should make the terrain clip.
  2. The planes are skewed and not aligned between the coordinates they are drawn between. I can see there are differences based on position on the globe, but I would like to know if there is a more robust way to construct the position/orientation of planes with arbitrary coordinates. I have temporarily hardcoded a solution locally on my machine using a Matrix3 rotation.

Are there any suggestions to how I could move forward to solve this? Most of the information I could find online has been tried without me getting any wiser. Any hints, solutions or resources on how to solve this are appreciated.

Sandcastle

The planes are skewed and not aligned between the coordinates they are drawn between. I can see there are differences based on position on the globe, but I would like to know if there is a more robust way to construct the position/orientation of planes with arbitrary coordinates.

The planes are assigned a certain orientation (as you noticed: depending on the position). When you change the code that creates the plane to…

          const bluePlane = viewer.entities.add({
              name: "Blue plane",
              position: midpoint,

              // --------------------------------------------- ADD THIS LINE:
              orientation: new Cesium.Quaternion(0, 0, 0, 1), // Identity

              plane: {
                plane: new Cesium.Plane(normal, 0.0),
                dimensions: new Cesium.Cartesian2(15.0, 5.0),
                material: Cesium.Color.BLUE.withAlpha(0.5),
              },
          });

then the orientation of the planes should match what you expect.


Beyond that: Some questions related to clipping planes come up pretty frequently. I wrote a few general words in Clipping only a portion of 3d Tileset - #2 by Marco13 (which, in turn, is a description of some details from How to load only 3dtiles inside the polygon? - #7 by Marco13 ).

I tried to follow the computations in your sandcastle, but it requires a bit of time and effort to go through the code and figure out where exactly something goes wrong - particularly, since “something being wrong” might very well just be a sign error (e.g. some wrong order in some cross product, or maybe a point missing in some list).

So I re-used a few snippets from the sandcastles that I created in the threads above, and created this:

https://sandcastle.cesium.com/index.html#c=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

It takes the line that you defined, creates a polygon (“trench”) with a certain width, and then uses the points of this polygon to create a bunch of clipping planes. This is broken into a few functions with // short comments that hopefully show the most important steps:

  • Create a version of that line that is shifted “right”
  • Create a version of that line that is shifted “left”
  • Concatenate these (reversing the second list) to create a “polygon”
  • Create clipping planes from each two consecutive points of that polygon
  • Throw these clipping planes into a ClippingPlaneCollection

Note that the ClippingPlaneCollection has an inherent limitation: It can, by principle, always and only represent a convex polygon. When the “trench” that you are modeling there is not just a straight line, then this approach plainly won’t work. In that case, you should be able to simply use clipping polygons which have recently been introduced, are described in the blog post at Hide Regions of 3D Tiles or Terrain with Clipping Polygons – Cesium , and might be exactly what you’re looking for.

I tried it out, and the Sandcastle does include that approach (just uncomment the useClippingPolygon() call at the bottom). But unfortunately, there seems to be some precision issue when applying this to the given terrain: The polygon is not represented cleanly when it is very narrow. (When setting width = 10.0, then it somehow works, but still not perfectly).

1 Like

Thank you for the detailed response. This is really useful.

I’ll be testing some of your snippets right away to see where things went wrong in my example.

My sandcastle example is unfortunately a bit messy since it has undergone several rewrites with different methods. It is however good to see that we have the same thought process on how the logic should be broken down.

I have already tried ClippingPolygonCollection, but I experienced the exact same problem as in your sandbox. Seems to be an issue in the Clipping Regions Demo as well. Unfortunately, there are widths down to a minimum of 0.6 we will have to work with.

The ultimate goal is to extract points from a polyline, form a shape between each point, then create the clipping path (planes). The trench can have different angles, but will ultimately be a combination of straight lines which needs to be connected. I believe this can be solved with additional logic, as the offset coordinates won’t be “connected”. e.g. finding a midpoint.

Example

ClippingPlaneCollection seems to do the trick here, even with its limitations. The clipping will be used in smaller areas, and a visualization without noise would be optimal. Is it the terrain provider that makes the clipping shape “stutter” when moving the camera? It’s a noticable difference compared to the Terrain Clipping Planes Demo.

Is it the terrain provider that makes the clipping shape “stutter” when moving the camera?

I also noticed that. And I cannot pinpoint the exact reason. Some guesses:

  • It might be related to the terrain provider, but in a non-obvious way. (Using that terrain provider in the “Terrain Clipping Planes” Sandcastle does not show that ‘jittering’).
  • It might be related to the geographical location. Usually, the poles are more difficult than the equator (in terms of precision). But the line here is at 62 degrees, which should not cause an issue…
  • It might also also be the fact that the line that is supposed to be carved out is really tiny…

This may warrant some further investigation (it may be worth tracking that in an issue, but preferably, with more detail about the conditions under which this ‘jittering’ can be observed)

I believe this can be solved with additional logic, as the offset coordinates won’t be “connected”. e.g. finding a midpoint.

Yes, if this is supposed to be a “wide polyline”, then the question about the exact outline comes into play.
(An aside: All this is already solved within CesiumJS, on the level of drawing polylines - but I don’t think that there is a way how this is explicility exposed in the API).
A usually important degree of freedom is the connection method for the ‘joins’, being ‘bevel’, ‘round’, or ‘miter’. But… to some extent this may become obsolete: WIth the clipping planes being “infinitely large”, the join style could become ‘miter’ automatically. The midpoints in your image could just be computed as the intersections of the respective outline parts. When there are very narrow angles, then there are (literally) corner cases that have to be considered, but that may not be important right now…

The more important point is: The ClippingPlaneCollection can only model convex shapes.

So I think that the only solution will be to use the clipping polygons that have been added with Allow users to define clipping regions with polygons by ggetz · Pull Request #11750 · CesiumGS/cesium · GitHub . I asked about the precision issue internally, maybe there’s a solution for that (or maybe it has to be tracked in a dedicated issue as well).

It might also also be the fact that the line that is supposed to be carved out is really tiny…

By using your modified sandcastle example and adjusting width to 100, it seems to be the same amount of jittering, just a bit less noticeable because of the scale.

The more important point is: The ClippingPlaneCollection can only model convex shapes.

Yes, that explains some of the problems I’ve had with ClippingPlaneCollection.

For the shape in my example to be shown underground I see three options:

  1. Use ClippingPlaneCollection.
    Pros
    Works for our current use case with modifications. The user will have to manually choose through a custom interface which midpoint to construct the clippingPlanes from, given a midpoint between each coordinate in the polyline.
    Cons
    Can’t handle concave shapes.
    Produces jittering in terrain/shape on provided coordinates / terrain provider.

  2. Use ClippingPolygonCollection.
    Pros
    More freedom in constructing the shape.
    Does not produce the same jittering as ClippingPlane.
    Cons
    Does not work in smaller areas. Requires that polygons support smaller areas or with higher precision.

  3. Use GlobeTranslucency
    Pros
    Can visualize the full shape underground.
    Cons
    Freedom of camera movement makes camera positioning unpredictable. Camera suddenly “jumps” to another position on the globe.

Thanks again for thorough information. I may create an issue on Github about the polygon size as that seems to be the optimal solution in our specific case. I’ll mark the question as solved since your answers have given me the information and perspective I need to move forward with the issue.