Skip to main content

Clipping Volumes

Clipping allows you to render only part of a scene. This can be useful to reveal internal structures that would otherwise be obscured by surrounding geometry, such as walls and outer shells.

note

Clipping volumes does not currently apply to dynamic objects!

Clipping volumes are formed by a set of planes, or halfspaces. Each halfspace is defined by a plane normal vector N^\hat{N} and an offset (negative distance) along that vector, OO. From this we can compute a signed distance to that plane for any given 3D coordinate (x,y,z)(x,y,z).

F(x,y,z)=xN^x+yN^y+zN^zOF(x, y, z) = x\hat{N}_x + y\hat{N}_y + z\hat{N}_z - O

This can be expressed as a 4D dot product where the w component of the input is -1.

const signed_distance = vec4.dot([x, y, z, -1], [nx, ny, nz, o]);

The positive side of this plane, i.e. signed_distance > 0, is considered outside the halfspace, whereas the negative side is inside. Points that lie outside will be clipped, while points inside will be rendered.

Single plane

To illustrate this, let's create a simple clipping volume with a single plane along the yz axes, effectively clipping everything to the right of center.

Single plane with offset

We used the center of the scene (which is far from origo) to position the plane. Let's add a few meters extra to observe the effect.

Single plane, flipped

You may flip the plane by flipping the direction of the normal. When doing so, also remember to negate the offset. Or, to put another way, simply negate all the elements [-nx,-ny,-nz,-o].

Single plane, rotated

Of course, you may use any normal you like for the plane, as long as its length is 1.0.

Dual plane

Adding additional planes allows us to further shape the clipping volume. Each plane forms a half space, which you may think of as the volume of everything that lies on the positive side of the plane to infinity. When combining multiple such half spaces, we must determine whether to use the intersection or union of these halfspace volumes. Put simply, intersection is the volume that lies on the positive side of all the planes, while union is the volume that lines on the positive side of any of the planes.

outside_volume = outside_plane_1 && outside_plane_2; // intersection 
outside_volume = outside_plane_1 || outside_plane_2; // union
info

For those familiar with CSG (constructive solid geometry), the clipping volume is defined by a simple CSG expression.

Let's create a more complex clipping volume with an additional plane along the xz axes, effectively clipping everything to the right and in front of center.

Dual plane, slab

A perhaps more useful volume is a slab, consisting of a top and bottom plane, but otherwise extending into infinity.

Inverted slab

If you wish to clip everything inside of the volume, rather than outside, simply flip the planes (negate all elements) and change the combination mode.

Box

We currently support up to 6 planes, allowing you to define simple polyhedra of any size, rotation and position. Let's define an axis aligned clipping box.

Outlines

You can also enable outline rendering, which will render lines where the geometry intersects a clipping plane. This feature is particularly useful for orthographic projections, where surfaces perpendicular to the camera would otherwise be invisible.

Due to limitations in the WebGL2 API, outline rendering has a significant memory overhead. Every clipping plane you enable it on will also incur an extra performance cost.

Because of the performance and memory hit of the outline feature, not all devices will have it enabled. You can check if it is available in the view's View.deviceProfile under DeviceProfile.features.

info

Use outline feature with caution, particularly on weaker devices.

Visualization

Finally, you can visualize clipping planes directly by setting RenderStateClipping.draw to true. By default, RenderStateClippingPlane.color is undefined, which will render nothing. To visualize a specific plane, you need to set this color to a an 4D RGBA vector/array. The alpha component lets you draw the planes transparently when less than 1.0.

Note that clipping planes are only drawn when the camera is on the positive side, i.e. outside the plane halfspace. Rotate the camera to see how the planes disappear when viewed from inside. This means that if you have a box, only three of the six clipping planes will be rendered at any given camera position, allowing you to interact with them without interference.

Picking

Visualization also allows you to interact with the planes just like any other pickable object. This could be useful for making a UI where users can push/pull the position of each plane interactively. The planes will have one of the object IDs in the ClippingId, in the order by which they are listed respectively.

For more detail on object picking, please see the Object selection guide!

Picking and making plane from normal

In the demo below we'll show how can we pick any object and make a plane out of it by using PickSample.normal, you'll also notice that we're checking for PickSampleExt.sampleType to pick the surface only, you can also check for other types which include edge and corner.

tip

Click anywhere on the model to see planes.