Dela via


Översikt över 3D-grafik

3D-funktionerna i Windows Presentation Foundation (WPF) gör det möjligt för utvecklare att rita, transformera och animera 3D-grafik i både markerings- och procedurkod. Utvecklare kan kombinera 2D- och 3D-grafik för att skapa omfattande kontroller, tillhandahålla komplexa illustrationer av data eller förbättra användarupplevelsen i ett programs gränssnitt. 3D-stöd i WPF är inte utformat för att tillhandahålla en komplett spelutvecklingsplattform. Det här avsnittet innehåller en översikt över 3D-funktioner i WPF-grafiksystemet.

3D i en 2D-behållare

3D-grafikinnehåll i WPF är inkapslat i ett element, Viewport3D, som kan delta i den tvådimensionella elementstrukturen. Grafiksystemet behandlar Viewport3D som ett tvådimensionellt visuellt element som många andra i WPF. Viewport3D fungerar som ett fönster – ett visningsområde – i en tredimensionell scen. Mer exakt är det en yta där en 3D-scen projiceras.

I ett konventionellt 2D-program använder du Viewport3D på samma sätt som med ett annat containerelement som Grid eller Canvas. Även om du kan använda Viewport3D med andra 2D-ritobjekt i samma scendiagram kan du inte mellananvända 2D- och 3D-objekt inom en Viewport3D. Det här avsnittet fokuserar på hur du ritar 3D-grafik i Viewport3D.

3D-koordinatutrymme

WPF-koordinatsystemet för 2D-grafik lokaliserar ursprunget i det övre vänstra återgivningsområdet (vanligtvis skärmen). I 2D-systemet fortsätter positiva x-axelvärden till höger och positiva y-axelvärden fortsätter nedåt. I 3D-koordinatsystemet finns ursprunget i mitten av återgivningsområdet, med positiva x-axelvärden som fortsätter åt höger men positiva y-axelvärden fortsätter uppåt i stället, och positiva z-axelvärden fortsätter utåt från ursprunget, mot visningsprogrammet.

Koordinatsystem
Konventionella 2D- och 3D-koordinatsystemrepresentationer

Det utrymme som definieras av dessa axlar är den stationära referensramen för 3D-objekt i WPF. När du skapar modeller i det här utrymmet och skapar lampor och kameror för att visa dem är det bra att skilja den här stationära referensramen eller "världsutrymmet" från den lokala referensram som du skapar för varje modell när du tillämpar transformeringar på den. Kom också ihåg att objekt i världsrymden kan se helt annorlunda ut, eller inte vara synliga alls, beroende på ljus- och kamerainställningar, men kamerans position ändrar inte platsen för objekt i världsrymden.

Kameror och projektioner

Utvecklare som arbetar i 2D är vana vid att placera ritprimitiver på en tvådimensionell skärm. När du skapar en 3D-scen är det viktigt att komma ihåg att du verkligen skapar en 2D-representation av 3D-objekt. Eftersom en 3D-scen ser annorlunda ut beroende på åskådarens synvinkel måste du ange den vyn. Med klassen Camera kan du ange den här vyn för en 3D-scen.

Ett annat sätt att förstå hur en 3D-scen representeras på en 2D-yta är genom att beskriva scenen som en projektion på visningsytan. Med ProjectionCamera kan du ange olika projektioner och deras egenskaper för att ändra hur åskådaren ser 3D-modeller. En PerspectiveCamera anger en projektion som förkortar scenen. Med andra ord ger PerspectiveCamera flyktpunktsperspektiv. Du kan ange kamerans position i scenens koordinatutrymme, kamerans riktning och synfält och en vektor som definierar riktningen för "upp" i scenen. Följande diagram illustrerar PerspectiveCameraprojektion.

Egenskaperna NearPlaneDistance och FarPlaneDistance för ProjectionCamera begränsa räckvidden för kamerans projektion. Eftersom kameror kan finnas var som helst i scenen, är det möjligt för kameran att faktiskt placeras inuti en modell eller mycket nära en modell, vilket gör det svårt att skilja objekt korrekt. NearPlaneDistance gör att du kan ange ett minsta avstånd från kameran utöver vilka objekt inte kommer att ritas. Med FarPlaneDistance kan du däremot ange ett avstånd från kameran där objekt inte ritas, vilket säkerställer att objekt som är för långt borta för att kunna identifieras inte tas med i scenen.

Kamerainstallation
Kameraläge

OrthographicCamera anger en ortogonial projektion av en 3D-modell till en visuell 2D-yta. Liksom andra kameror anger den en position, visningsriktning och "uppåt"-riktning. Till skillnad från PerspectiveCamerabeskriver dock OrthographicCamera en projektion som inte innehåller perspektivisk förkortning. Med andra ord beskriver OrthographicCamera en visningsruta vars sidor är parallella, i stället för en vars sidor möts i en punkt vid kameran. Följande bild visar samma modell som visas med hjälp av PerspectiveCamera och OrthographicCamera.

Ortografisk och perspektivprojektion
Perspektiv- och ortografiska projektioner

Följande kod visar några typiska kamerainställningar.

// Defines the camera used to view the 3D object. In order to view the 3D object,
// the camera must be positioned and pointed such that the object is within view
// of the camera.
PerspectiveCamera myPCamera = new PerspectiveCamera();

// Specify where in the 3D scene the camera is.
myPCamera.Position = new Point3D(0, 0, 2);

// Specify the direction that the camera is pointing.
myPCamera.LookDirection = new Vector3D(0, 0, -1);

// Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60;

// Asign the camera to the viewport
myViewport3D.Camera = myPCamera;
' Defines the camera used to view the 3D object. In order to view the 3D object,
' the camera must be positioned and pointed such that the object is within view 
' of the camera.
Dim myPCamera As New PerspectiveCamera()

' Specify where in the 3D scene the camera is.
myPCamera.Position = New Point3D(0, 0, 2)

' Specify the direction that the camera is pointing.
myPCamera.LookDirection = New Vector3D(0, 0, -1)

' Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60

' Asign the camera to the viewport
myViewport3D.Camera = myPCamera

Modell- och mesh-primitiver

Model3D är den abstrakta basklassen som representerar ett generiskt 3D-objekt. För att skapa en 3D-scen behöver du vissa objekt att visa och de objekt som utgör scendiagrammet härleds från Model3D. För närvarande stöder WPF modelleringsgeometrier med GeometryModel3D. Egenskapen Geometry för den här modellen använder en mesh-primitiv.

För att bygga en modell, börja med att skapa en primitiv eller ett nät. En 3D-primitiv är en samling hörn som utgör en enda 3D-entitet. De flesta 3D-system ger primitiver modellerade på den enklaste slutna figuren: en triangel som definieras av tre hörn. Eftersom de tre punkterna i en triangel är coplanar kan du fortsätta att lägga till trianglar för att modellera mer komplexa former, så kallade nät.

WPF 3D-systemet tillhandahåller för närvarande klassen MeshGeometry3D, vilket gör att du kan ange valfri geometri. det stöder för närvarande inte fördefinierade 3D-primitiver som sfärer och kubikformer. Börja skapa en MeshGeometry3D genom att ange en lista över triangelhörn som dess Positions egenskap. Varje hörn anges som en Point3D. (I XAML anger du den här egenskapen som en lista med tal grupperade i treor som representerar koordinaterna för varje hörn.) Beroende på geometrin kan ditt nät bestå av många trianglar, varav vissa delar samma hörn (hörn). För att rita nätet korrekt behöver WPF information om vilka hörn som delas av vilka trianglar. Du anger den här informationen genom att ange en lista över triangelindex med egenskapen TriangleIndices. Den här listan anger i vilken ordning punkterna som anges i listan Positions avgör en triangel.

<GeometryModel3D>
  <GeometryModel3D.Geometry>
          <MeshGeometry3D 
              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"
              TextureCoordinates="0 1  1 1  0 0  1 0   "
              TriangleIndices="0 1 2  1 3 2" />
      </GeometryModel3D.Geometry>
      <GeometryModel3D.Material>
          <DiffuseMaterial>
              <DiffuseMaterial.Brush>
                  <SolidColorBrush Color="Cyan" Opacity="0.3"/>
              </DiffuseMaterial.Brush>
          </DiffuseMaterial>
      </GeometryModel3D.Material>
  <!-- Translate the plane. -->
      <GeometryModel3D.Transform>
          <TranslateTransform3D
            OffsetX="2" OffsetY="0" OffsetZ="-1"   >
          </TranslateTransform3D>
      </GeometryModel3D.Transform>
  </GeometryModel3D>

I föregående exempel anger listan Positions fyra hörn för att definiera ett rektangelnät. Egenskapen TriangleIndices anger en lista över två grupper med tre index. Varje tal i listan refererar till en förskjutning i listan Positions. Till exempel är de första tre hörnen som anges i listan Positions(-1,-1,0), (1,-1,0)och (-1,1,0). De första tre indexen som anges i listan med TriangleIndices är 0, 1 och 2, vilket motsvarar den första, andra och tredje poängen i listan över Positions. Därför består den första triangeln som utgör rektangelns modell från (-1,-1,0) till (1,-1,0) till (-1,1,0)och den andra triangeln bestäms på samma sätt.

Du kan fortsätta att definiera modellen genom att ange värden för egenskaperna Normals och TextureCoordinates. För att återge modellens yta behöver grafiksystemet information om vilken riktning ytan är riktad mot vid en viss triangel. Den använder den här informationen för att göra ljusberäkningar för modellen: ytor som möter direkt mot en ljuskälla verkar ljusare än de som vinklas bort från ljuset. Även om WPF kan fastställa standardnormala vektorer med hjälp av positionskoordinaterna, kan du också ange olika normala vektorer för att approximera utseendet på böjda ytor.

Egenskapen TextureCoordinates anger en samling Pointsom talar om för grafiksystemet hur koordinaterna som avgör hur en textur ritas appliceras på nätets vertikaler. TextureCoordinates anges som ett värde mellan noll och 1, inklusive. Precis som med egenskapen Normals kan grafiksystemet beräkna standardkoordinater för textur, men du kan välja att ange olika strukturkoordinater för att styra mappningen av en struktur som innehåller en del av ett upprepande mönster, till exempel. Mer information om strukturkoordinater finns i efterföljande avsnitt eller i Managed Direct3D SDK.

I följande exempel visas hur du skapar ett ansikte för kubmodellen i procedurkod. Du kan rita hela kuben som en enda GeometryModel3D; I det här exemplet ritas kubens ansikte som en distinkt modell för att kunna använda separata texturer för varje ansikte senare.

MeshGeometry3D side1Plane = new MeshGeometry3D();
Private side1Plane As New MeshGeometry3D()
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));

side1Plane.TriangleIndices.Add(0);
side1Plane.TriangleIndices.Add(1);
side1Plane.TriangleIndices.Add(2);
side1Plane.TriangleIndices.Add(3);
side1Plane.TriangleIndices.Add(4);
side1Plane.TriangleIndices.Add(5);

side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));

side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))

side1Plane.TriangleIndices.Add(0)
side1Plane.TriangleIndices.Add(1)
side1Plane.TriangleIndices.Add(2)
side1Plane.TriangleIndices.Add(3)
side1Plane.TriangleIndices.Add(4)
side1Plane.TriangleIndices.Add(5)

side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))

side1Plane.TextureCoordinates.Add(New Point(1, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 0))

"

Tillämpa material på modellen

För att ett nät ska se ut som ett tredimensionellt objekt måste det ha en tillämpad struktur för att täcka ytan som definieras av dess hörn och trianglar så att den kan tändas och projiceras av kameran. I 2D använder du klassen Brush för att tillämpa färger, mönster, toningar eller annat visuellt innehåll på områden på skärmen. Utseendet på 3D-objekt är dock en funktion av belysningsmodellen, inte bara av färgen eller mönstret som tillämpas på dem. Verkliga objekt reflekterar ljus på olika sätt beroende på kvaliteten på deras ytor: glansiga och glänsande ytor ser inte likadana ut som grova eller matta ytor, och vissa objekt verkar absorbera ljus medan andra lyser. Du kan använda samma penslar på 3D-objekt som du kan använda för 2D-objekt, men du kan inte tillämpa dem direkt.

För att definiera egenskaperna för en modells yta använder WPF den Material abstrakta klassen. De konkreta underklasserna av Material bestämmer några av utseendeegenskaperna för modellens yta, och var och en ger också en Brush-egenskap som du kan skicka en SolidColorBrush, TileBrush eller VisualBrush till.

  • DiffuseMaterial anger att penseln ska tillämpas på modellen som om den vore diffust belyst. Att använda DiffuseMaterial liknar mest att använda penslar direkt på 2D-modeller; modellytor reflekterar inte ljus som om de var glänsande.

  • SpecularMaterial anger att penseln ska tillämpas på modellen som om modellens yta var hård eller glänsande och kunde reflektera markeringar. Du kan ange i vilken grad strukturen ska föreslå den här reflekterande kvaliteten eller "glansen" genom att ange ett värde för egenskapen SpecularPower.

  • EmissiveMaterial kan du ange att strukturen ska tillämpas som om modellen avgav ljus som motsvarar penselns färg. Detta gör inte modellen till en lampa; den kommer dock att bete sig annorlunda i skuggning än om den vore texturerad med DiffuseMaterial eller SpecularMaterial.

För bättre prestanda gallras baksidan av en GeometryModel3D (de ansikten som är utom synfältet eftersom de är på motsatta sidan av modellen från kameran) från scenen. Ange en Material som ska tillämpas på baksidan av en modell som ett plan genom att ange modellens BackMaterial egenskap.

För att uppnå vissa ytegenskaper, till exempel glödande eller reflekterande effekter, kanske du vill tillämpa flera olika penslar på en modell i följd. Du kan använda och återanvända flera material med hjälp av klassen MaterialGroup. Barnen i MaterialGroup tillämpas från första till sista i flera renderingspass.

Följande kodexempel visar hur du använder en solid färg och en ritning som penslar på 3D-modeller.

<GeometryModel3D.Material>
    <DiffuseMaterial>
        <DiffuseMaterial.Brush>
            <SolidColorBrush Color="Cyan" Opacity="0.3"/>
        </DiffuseMaterial.Brush>
    </DiffuseMaterial>
</GeometryModel3D.Material>
<DrawingBrush x:Key="patternBrush" Viewport="0,0,0.1,0.1" TileMode="Tile">
  <DrawingBrush.Drawing>
    <DrawingGroup>
      <DrawingGroup.Children>
        <GeometryDrawing Geometry="M0,0.1 L0.1,0 1,0.9, 0.9,1z"
          Brush="Gray" />
        <GeometryDrawing Geometry="M0.9,0 L1,0.1 0.1,1 0,0.9z"
          Brush="Gray" />
        <GeometryDrawing Geometry="M0.25,0.25 L0.5,0.125 0.75,0.25 0.5,0.5z"
          Brush="#FFFF00" />
        <GeometryDrawing Geometry="M0.25,0.75 L0.5,0.875 0.75,0.75 0.5,0.5z"
          Brush="Black" />
        <GeometryDrawing Geometry="M0.25,0.75 L0.125,0.5 0.25,0.25 0.5,0.5z"
          Brush="#FF0000" />
        <GeometryDrawing Geometry="M0.75,0.25 L0.875,0.5 0.75,0.75 0.5,0.5z"
          Brush="MediumBlue" />
      </DrawingGroup.Children>
    </DrawingGroup>
  </DrawingBrush.Drawing>
</DrawingBrush>
DiffuseMaterial side5Material = new DiffuseMaterial((Brush)Application.Current.Resources["patternBrush"]);
Dim side5Material As New DiffuseMaterial(CType(Application.Current.Resources("patternBrush"), Brush))

Belysa scenen

Lampor i 3D-grafik gör vad lampor gör i den verkliga världen: de gör ytor synliga. Mer till saken, lampor avgör vilken del av en scen som kommer att ingå i projektionen. Ljusobjekt i WPF skapar en mängd olika ljus- och skuggeffekter och modelleras efter beteendet hos olika verkliga ljus. Ta med minst ett ljus i scenen, annars visas inga modeller.

Följande ljus härleds från basklassen Light:

  • AmbientLight: Ger omgivande belysning som lyser upp alla objekt på ett enhetligt sätt oavsett plats eller orientering.

  • DirectionalLight: Lyser som en avlägsen ljuskälla. Riktningsljus har Direction som en Vector3D, men ingen angiven position.

  • PointLight: Lyser som en ljuskälla i närheten. PointLights har en position och sprider ljus från den positionen. Föremål i scenen belyses beroende på deras position och avstånd med avseende på ljuset. PointLightBase exponerar en Range egenskap, som avgör ett avstånd bortom vilket modeller inte kommer att belysas av ljuset. PointLight exponerar också dämpningsegenskaper, som avgör hur ljusets intensitet minskar över avstånd. Du kan ange konstanta, linjära eller kvadratiska interpolationer för ljusets dämpning.

  • SpotLight: Ärver från PointLight. Spotlights fungerar som PointLight och har både position och riktning. De projicerar ljus i ett konformat område som InnerConeAngle och OuterConeAngle-egenskapernas inställningar anger i grader.

Lampor är Model3D objekt, så du kan transformera och animera ljusegenskaper, inklusive position, färg, riktning och intervall.

<ModelVisual3D.Content>
    <AmbientLight Color="#333333" />
</ModelVisual3D.Content>
DirectionalLight myDirLight = new DirectionalLight();
Private myDirLight As New DirectionalLight()
myDirLight.Color = Colors.White;
myDirLight.Direction = new Vector3D(-3, -4, -5);
myDirLight.Color = Colors.White
myDirLight.Direction = New Vector3D(-3, -4, -5)
modelGroup.Children.Add(myDirLight);
modelGroup.Children.Add(myDirLight)

Transformera modeller

När du skapar modeller har de en viss plats i scenen. Om du vill flytta runt modellerna i scenen, rotera dem eller ändra deras storlek är det inte praktiskt att ändra hörnen som definierar själva modellerna. I stället, precis som i 2D, tillämpar du transformeringar på modeller.

Varje modellobjekt har en Transform egenskap som du kan flytta, ändra eller ändra storlek på modellen med. När du tillämpar en transformering förskjuter du effektivt alla punkter i modellen med den vektor eller det värde som anges av transformeringen. Med andra ord har du omvandlat koordinatutrymmet där modellen definieras ("modellutrymme"), men du har inte ändrat de värden som utgör modellens geometri i koordinatsystemet för hela scenen ("världsrymd").

Mer information om hur du transformerar modeller finns i 3D Transformations Overview.

Animera modeller

WPF 3D-implementeringen deltar i samma tids- och animeringssystem som 2D-grafik. För att animera en 3D-scen animerar du med andra ord egenskaperna för dess modeller. Det är möjligt att animera egenskaper för primitiver direkt, men det är vanligtvis enklare att animera transformeringar som ändrar positionen eller utseendet på modeller. Eftersom transformationer kan tillämpas på Model3DGroup objekt såväl som på enskilda modeller, är det möjligt att tillämpa en uppsättning animeringar på ett barnobjekt av en Model3DGroup och en annan uppsättning animeringar på en grupp av underordnade objekt. Du kan också uppnå en mängd olika visuella effekter genom att animera egenskaperna för scenens belysning. Slutligen kan du välja att animera själva projektionen genom att animera kamerapositionen eller visningsfältet. Bakgrundsinformation om WPF-tids- och animeringssystemet finns i Animationsöversikt, Storyboard-översiktoch översikt över friserbara objekt.

Om du vill animera ett objekt i WPF skapar du en tidslinje, definierar en animering (vilket verkligen är en ändring i ett egenskapsvärde över tid) och anger den egenskap som animeringen ska tillämpas på. Eftersom alla objekt i en 3D-scen är underordnade Viewport3D, är egenskaperna som riktas mot av vilken animering du vill applicera på scenen egenskaper hos Viewport3D.

Anta att du vill att en modell ska se ut att svänga på plats. Du kan välja att tillämpa en RotateTransform3D på modellen och animera axeln för dess rotation från en vektor till en annan. Följande kodexempel visar hur du tillämpar en Vector3DAnimation på axelegenskapen för omvandlingens Rotation3D, förutsatt att RotateTransform3D är en av flera transformeringar som tillämpas på modellen med en TransformGroup.

//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation);
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation)
//Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform);
'Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform)

Lägg till 3D-innehåll i fönstret

Om du vill återge scenen lägger du till modeller och lampor i en Model3DGroupoch anger sedan Model3DGroup som Content för en ModelVisual3D. Lägg till ModelVisual3D till Children-samlingen för Viewport3D. Lägg till kameror i Viewport3D genom att ange dess egenskap Camera.

Lägg slutligen till Viewport3D i fönstret. När Viewport3D ingår som innehåll i ett layoutelement som Canvas anger du storleken på Viewport3D genom att ange dess egenskaper för Height och Width (ärvda från FrameworkElement).

<UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
  
    <Grid>

      <!-- Place a Label control at the top of the view. -->
      <Label 
                HorizontalAlignment="Center" 
                TextBlock.TextAlignment="Center" 
                FontSize="20" 
                Foreground="Red" 
                Content="Model: Cone"/>

      <!-- Viewport3D is the rendering surface. -->
      <Viewport3D Name="myViewport" >

        <!-- Add a camera. -->
        <Viewport3D.Camera>
          <PerspectiveCamera 
                        FarPlaneDistance="20" 
                        LookDirection="0,0,1" 
                        UpDirection="0,1,0" 
                        NearPlaneDistance="1" 
                        Position="0,0,-3" 
                        FieldOfView="45" />
        </Viewport3D.Camera>

        <!-- Add models. -->
        <Viewport3D.Children>

          <ModelVisual3D>
            <ModelVisual3D.Content>

              <Model3DGroup >
                <Model3DGroup.Children>

                  <!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
                  <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />

                  <!-- Define a red cone. -->
                  <GeometryModel3D>

                    <GeometryModel3D.Geometry>
                      <MeshGeometry3D 
    Positions="0.293893 -0.5 0.404509  0.475528 -0.5 0.154509  0 0.5 0  0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 0.154509  0.475528 -0.5 -0.154509  0 0.5 0  0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 -0.154509  0.293893 -0.5 -0.404509  0 0.5 0  0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  0.293893 -0.5 -0.404509  0 -0.5 -0.5  0 0.5 0  0 -0.5 -0.5  0 0.5 0  0 0.5 0  0 -0.5 -0.5  -0.293893 -0.5 -0.404509  0 0.5 0  -0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  -0.293893 -0.5 -0.404509  -0.475528 -0.5 -0.154509  0 0.5 0  -0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 -0.154509  -0.475528 -0.5 0.154509  0 0.5 0  -0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 0.154509  -0.293892 -0.5 0.404509  0 0.5 0  -0.293892 -0.5 0.404509  0 0.5 0  0 0.5 0  -0.293892 -0.5 0.404509  0 -0.5 0.5  0 0.5 0  0 -0.5 0.5  0 0.5 0  0 0.5 0  0 -0.5 0.5  0.293893 -0.5 0.404509  0 0.5 0  0.293893 -0.5 0.404509  0 0.5 0  0 0.5 0  " 
    Normals="0.7236065,0.4472139,0.5257313  0.2763934,0.4472138,0.8506507  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  -0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.5308242,0.4294462,0.7306172  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.7236065,0.4472139,0.5257313  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.858892,0.429446,0.279071  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.8944269,0.4472139,0  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.858892,0.429446,-0.279071  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.7236065,0.4472139,-0.5257313  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.5308242,0.4294462,-0.7306172  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.2763934,0.4472138,-0.8506507  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.5308249,0.4294459,-0.7306169  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.7236068,0.4472141,-0.5257306  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8588922,0.4294461,-0.27907  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8944269,0.4472139,0  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.858892,0.429446,0.279071  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.7236065,0.4472139,0.5257313  0.858892,0.429446,0.279071  0.7236065,0.4472139,0.5257313  0.5308242,0.4294462,0.7306172  0.858892,0.429446,0.279071  "                   TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
                    </GeometryModel3D.Geometry>

                    <GeometryModel3D.Material>
                      <DiffuseMaterial>
                        <DiffuseMaterial.Brush>
                          <SolidColorBrush 
                            Color="Red" 
                            Opacity="1.0"/>
                        </DiffuseMaterial.Brush>
                      </DiffuseMaterial>
                    </GeometryModel3D.Material>

                  </GeometryModel3D>

                </Model3DGroup.Children>
              </Model3DGroup>

            </ModelVisual3D.Content>

          </ModelVisual3D>

        </Viewport3D.Children>

      </Viewport3D>
    </Grid>
  
</UserControl>

Se även