Pages

Showing posts with label 3D. Show all posts
Showing posts with label 3D. Show all posts

Saturday, 3 December 2011

3D VisualBrush and TextureCoordinates

This post starts with the last example from the 3D Towards a Solid post.
The previous examples all used a single colour for the Material applied to a surface.
This example replaces the Brush with a StackPanel containing a TextBlock and Button.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>

                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>

                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
At this point the front of the cube will be transparent and the TextBlock and Button will not appear. We need to add TextCoordinates to map the VisualBrush to the Mesh.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>

                     <MeshGeometry3D.TextureCoordinates>0,1 1,1 1,0 0,0</MeshGeometry3D.TextureCoordinates>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
To apply the texture to the "back" of the we need to "flip" the TextureCoordinates horizontally around the Y axis to match the way we previously changed the TriangleIndices.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>

                     <MeshGeometry3D.TextureCoordinates>1,1 0,1 0,0 1,0</MeshGeometry3D.TextureCoordinates>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Back!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                     <MeshGeometry3D.TextureCoordinates>0,1 1,1 1,0 0,0</MeshGeometry3D.TextureCoordinates>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>
                        <VisualBrush>
                           <VisualBrush.Visual>
                              <StackPanel>
                                 <TextBlock FontSize="10pt"
                                            Margin="2">Hello, from the Front!</TextBlock>
                                 <Button Margin="2">A Button</Button>
                              </StackPanel>
                           </VisualBrush.Visual>
                        </VisualBrush>
                     </DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>

3D Towards a Solid

This post starts with the last example from the 3D Rotation post. I want to add a second face of a cube, opposite the original surface. First add a Model3DGroup to contain all the GeometryModel3D elements that will form the cube.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>

            <Model3DGroup>

            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>

            </Model3DGroup>

         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
And add the second surface exactly the same as the first but with the Z coordinates moved from -0.5 to +0.5.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>

            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>

            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
We can now see two Maroon/Blue surfaces rotating but we always see the same colour for both surfaces. The original surface needs to point "out" from the centre of the cube. The easiest way would appear to be drawing the Triangles in a different order so their Normals are reversed. Swap 0 and 1, swap 2 and 3 in the TriangleIndices list.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>

                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>
Finally, add the remaining two vertical surfaces of the cube. The "left" surface uses the same TriangleIndices as the "front" whereas the "right" surface uses the same TriangleIndices as the "back".
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <Model3DGroup>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, +0.5  0.5, -0.5, +0.5  0.5, 0.5, +0.5  -0.5, 0.5, +0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>

                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  -0.5, -0.5, 0.5  -0.5, 0.5, 0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>

                     <MeshGeometry3D.Positions>0.5, -0.5, -0.5  0.5, -0.5, 0.5  0.5, 0.5, 0.5  0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>1 0 3 3 2 1</MeshGeometry3D.TriangleIndices>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
            </Model3DGroup>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>
</Grid>

3D Rotation

This post starts with the simple 3D model example from the first 3D post but with the camera moved back to its original position.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>
We want to rotate the Model around the Y axis, represented by the "1" in the definition of AxisAngleRotation3D.Axis below. Because the Model has a negative Z coordinate (-0.5) the Z component will gradually increase until the angle of rotation is 180 degrees at which point the Z coordinate becomes 0.5. Because the Z coordinate is closer to use the Model will appear larger.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
         </ModelVisual3D.Content>

         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D>
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>
                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>
                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>

      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>
Starting with an Angle of 0 (zero) degrees gives the same result as previously. Increasing the Angle to more than 90 degrees the reverse side of the Model comes into view.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D>
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>

                     <AxisAngleRotation3D.Angle>120</AxisAngleRotation3D.Angle>

                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>
The rotation can be animated by applying a DoubleAnimation to the RotateTransform.
Reset the Angle to zero, name the AxisAngleRotation3D and add a Grid.Trigger to start the animation.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
         </ModelVisual3D.Content>
         <ModelVisual3D.Transform>
            <RotateTransform3D>
               <RotateTransform3D.Rotation>
                  <AxisAngleRotation3D  x:Name="Rotate">
                     <AxisAngleRotation3D.Axis>0,1,0</AxisAngleRotation3D.Axis>

                     <AxisAngleRotation3D.Angle>0</AxisAngleRotation3D.Angle>

                  </AxisAngleRotation3D>
               </RotateTransform3D.Rotation>
            </RotateTransform3D>
         </ModelVisual3D.Transform>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>

   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.MouseDown">
         <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation From="0"
                                To="360"
                                BeginTime="0:0:0"
                                Duration="0:0:4"
                                Storyboard.TargetName="Rotate"
                                Storyboard.TargetProperty="Angle" />
            </Storyboard>
         </BeginStoryboard>
      </EventTrigger>
   </Grid.Triggers>

</Grid>

3D Foundations

To use 3D in WPF we need a minimum of an object, somewhere to draw it, a camera to see it and some light to illuminate the scene. Which in the following examples roughly correspond to GeometryModel3D, Viewport3D, PerspectiveCamera and AmbientLight respectively.
Starting with the Model and Viewport the bare minimum to describe a square is:
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
   </Viewport3D>
</Grid>
Each Mesh position is a triplet of X, Y and Z. Positive X is UP. Positive Y is RIGHT. Positive Z is OUT of the screen.
The Mesh triplets are numbered from 0 (zero) starting in BottomLeft and working anti-clockwise.

3 ------------ 2
|              |
|              |
|              |
0 ------------ 1
These form the indices used to cover the surface in triangles. Each triangle is drawn anti-clockwise to keep the "Normals" pointing in the same direction. I'm not going to mention Normals again.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>

                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>

                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
   </Viewport3D>
</Grid>
The model has two surfaces and each can have its own material. The front surface, Material, has been coloured Maroon.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
         
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>

            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
   </Viewport3D>
</Grid>
At this point nothing can be seen on screen because there is no camera.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
         
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>

   </Viewport3D>
</Grid>
At this point we should see a Black square which is the Maroon surface of the model in an unlit scene. Next we add some AmbientLight.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
      
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>
We should now be able to see a Maroon surface. The Model's reverse surface, BackMaterial, will be coloured Blue.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
      
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>

            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
            <PerspectiveCamera.LookDirection>0,0,-1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,2</PerspectiveCamera.Position>
            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>
Finally, reposition the camera and the direction it is looking in order to see the other side of the model. We should now see the blue surface.
<Grid Background="AliceBlue">
   <Viewport3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <GeometryModel3D>
               <GeometryModel3D.Geometry>
                  <MeshGeometry3D>
                     <MeshGeometry3D.Positions>-0.5, -0.5, -0.5  0.5, -0.5, -0.5  0.5, 0.5, -0.5  -0.5, 0.5, -0.5</MeshGeometry3D.Positions>
                     <MeshGeometry3D.TriangleIndices>0 1 2 2 3 0</MeshGeometry3D.TriangleIndices>
                  </MeshGeometry3D>
               </GeometryModel3D.Geometry>
               <GeometryModel3D.Material>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Maroon</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.Material>
               <GeometryModel3D.BackMaterial>
                  <DiffuseMaterial>
                     <DiffuseMaterial.Brush>Blue</DiffuseMaterial.Brush>
                  </DiffuseMaterial>
               </GeometryModel3D.BackMaterial>
            </GeometryModel3D>
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <ModelVisual3D>
         <ModelVisual3D.Content>
            <AmbientLight Color="White" />
         </ModelVisual3D.Content>
      </ModelVisual3D>
      <Viewport3D.Camera>
         <PerspectiveCamera>
      
            <PerspectiveCamera.LookDirection>0,0,1</PerspectiveCamera.LookDirection>
            <PerspectiveCamera.Position>0,0,-2</PerspectiveCamera.Position>

            <PerspectiveCamera.FieldOfView>90</PerspectiveCamera.FieldOfView>
         </PerspectiveCamera>
      </Viewport3D.Camera>
   </Viewport3D>
</Grid>