It’s a fairly common and standard trick to take advantage of the hardware acceleration afforded by modern graphic cards and render two-dimensional figures in 3D. Here is a simple and fast way to take the 3D out of a Viewport3D:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <Viewport3D> <Viewport3D.Camera> <OrthographicCamera Position="0,0,1" LookDirection="0,0,-1" UpDirection="0,1,0" Width="{Binding ActualWidth}" Height="{Binding ActualHeight}"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Children> <!-- render colors...relatively properly --> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="White"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D x:Name="SceneRoot"> <ModelVisual3D.Content> <!-- this is where stuff you want to render actually goes --> </ModelVisual3D.Content> </ModelVisual3D> </ModelVisual3D.Children> </ModelVisual3D> </Viewport3D> |
When the camera is set up this way, the center of the Viewport3D represents (0,0). The bottom-left is (−width / 2, −height / 2) and the top-right is (+width / 2, +height / 2).
Now what can you put in something like this? Same thing you’d normally put in a Viewport3D:
1 2 3 4 5 6 7 | <Model3DGroup> <GeometryModel3D Geometry="..."> <GeometryModel3D.Material> <DiffuseMaterial Brush="..."/> </GeometryModel3D.Material> </GeometryModel3D> </Model3DGroup> |
The Brush property can be any old System.Windows.Media.Brush. And as for that Geometry? Well, there are squares:
1 2 3 4 | <MeshGeometry3D x:Key="Square">
Positions="-1,-1,0 1,-1,0 1,1,0 -1,1,0"
Normals="0,0,1 0,0,1 0,0,1 0,0,1"
TriangleIndices="0 1 2 0 2 3"/> |
isosceles triangles:
1 2 3 4 | <MeshGeometry3D x:Key="IsoscelesTriangle">
Positions="-1,-1,0 1,-1,0 0,1,0"
Normals="0,0,1 0,0,1 0,0,1"
TriangleIndices="0 1 2"/> |
Coming up with these little nuggets of numbers is the topic of another post. But for now, some sample code:

Featuring basic hit-detection and a bit of interactivity (you can drag a square to increase/decrease the space between boxes, and change the angle of rotation). It’s pure WPF (no unsafe code or interop), it’s 2D, and it’s fast.
—DKT
Sorry the code formatting is off…the iPhone WordPress client totally destroyed it. I’ll fix it soonish.