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.
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 and an offset (negative distance) along that vector, . From this we can compute a signed distance to that plane for any given 3D coordinate .
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
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
.
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
.
Click anywhere on the model to see planes.