# Outline of plane slice of arbitrary object

How would you extract the outline of a shape from slicing a plane through an arbitrary object?

Note: This is related to my Unity Answers question, but not exactly the same.

• What kind of shape is it? Just an arbitrary triangle mesh? What do you need the outline for? Just rendering, or do you need to store the result? If you're just rendering it, this can be accomplished through a simple fragment shader. If you need it for computation, you will need to intersect the plane geometrically with the triangles of the object. – mklingen Apr 8 '15 at 0:57
• So, this is a dodecahedron, and a plane slicing it at the right angle will generate a hexagon outline... It's different for other meshes - such as a cylinder - you get circles or ovals or even rectangles depending on which angle you slice it at... – ina Apr 8 '15 at 9:12

This blog post describes an effect where the intersection between two object is highlighted. However, both object are rendered. I'm guessing in your case, you don't want the plane to be rendered. You could set the alpha for the plane's color to be 0. I think that will put the plane in the depth buffer, but not color it. But still, your object might intersect with any other object that was rendered before it.

Alternatively, you could create a texture that contains the depth map of just the plane, and within the fragment shader, sample the the plane depth, and if the fragment's depth is close, highlight that fragment's color.

I think you can use a secondary camera and a RenderTexture to get the depth map. I'm not sure how to make the second camera only render the plane.

A geometry shader might not be necessary.

I came up with a simplistic solution to this a few years ago in a non-realtime context (mesh slicing for 3d printing).

Given a plane defined in world coordinates by a point (origin) and a vector (normal). First setup a matrix that transforms your mesh into the coordinate system of the plane. Now do a z-bounds check of all the edges of the mesh (i.e. min(v1.z, v2.z) <= 0 and max(v1.z, v2.z) >= 0).

Each edge that passes the test is either in the plane (creates a line), or passes through at one point (creates a point). The point of intersect is the normalized vector from min point toward max point times the distance of the min point to the plane (z=0) as a percent of the change in the z axis along the edge...

# Pseudocode
low = v1 if v1.z < v2.z else v2
high = v2 if low is v1 else v1
zdelta = high.z - low.z
dist = abs(low.z) # Distance of low.z from plane
vec = normalize(high - low) # Assumes operator overload for vector arithmatic
intersect = vec * (dist/zdelta) # The x and y coord are all you need


Once you have a list of edges that create points in the plane you need to check for pairs that are part of the same face, draw lines connecting these. Also check both vertices of in-plane edges against other edges and connect those dots too.

This method works for arbitrary non-manifold meshes with ngon faces. In the context I wrote it I had access to half-winged edge mesh data with easy checks for membership. Given a closed triangle mesh you could probably simplify some of the checks?

old code