Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mit der 3D-Funktionalität in Windows Presentation Foundation (WPF) können Entwickler 3D-Grafiken sowohl im Markup als auch im prozeduralen Code zeichnen, transformieren und animieren. Entwickler können 2D- und 3D-Grafiken kombinieren, um umfangreiche Steuerelemente zu erstellen, komplexe Darstellungen von Daten bereitzustellen oder die Benutzeroberfläche einer Anwendung zu verbessern. Die 3D-Unterstützung in WPF ist nicht darauf ausgelegt, eine plattformübergreifende Spieleentwicklung bereitzustellen. Dieses Thema enthält eine Übersicht über die 3D-Funktionalität im WPF-Grafiksystem.
3D in einem 2D-Container
3D-Grafikinhalte in WPF werden in einem Element gekapselt, Viewport3Ddas an der zweidimensionalen Elementstruktur teilnehmen kann. Das Grafiksystem behandelt ein zweidimensionales visuelles Viewport3D Element wie viele andere in WPF. Viewport3D fungiert als Fenster – ein Viewport – in einer dreidimensionalen Szene. Genauer gesagt ist es eine Oberfläche, auf der eine 3D-Szene projiziert wird.
Verwenden Sie Viewport3D in einer herkömmlichen 2D-Anwendung, genauso wie Sie ein anderes Containerelement wie Grid oder Canvas verwenden würden. Obwohl Sie Viewport3D mit anderen 2D-Zeichnungsobjekten im selben Szenendiagramm verwenden können, können Sie 2D- und 3D-Objekte nicht innerhalb eines Viewport3D kombinieren. In diesem Thema wird erläutert, wie man 3D-Grafiken im Viewport3D zeichnet.
3D-Koordinatenraum
Das WPF-Koordinatensystem für 2D-Grafiken sucht den Ursprung oben links im Renderingbereich (in der Regel der Bildschirm). Im 2D-System gehen positive x-Achsenwerte nach rechts und positive Y-Achsenwerte nach unten. Im 3D-Koordinatensystem befindet sich der Ursprung jedoch in der Mitte des Renderingbereichs, wobei positive x-Achsenwerte nach rechts, positive y-Achsenwerte nach oben und positive z-Achsenwerte vom Ursprung aus in Richtung des Betrachters gehen.
Herkömmliche 2D- und 3D-Koordinatensystemdarstellungen
Der durch diese Achsen definierte Raum ist der stationäre Bezugsrahmen für 3D-Objekte in WPF. Wenn Sie Modelle in diesem Raum erstellen und Lichter und Kameras erstellen, um sie anzuzeigen, ist es hilfreich, diesen stationären Referenzrahmen oder "Weltraum" vom lokalen Referenzrahmen zu unterscheiden, den Sie für jedes Modell erstellen, wenn Sie Transformationen darauf anwenden. Denken Sie auch daran, dass Objekte im Weltraum je nach Licht- und Kameraeinstellungen völlig anders aussehen oder gar nicht sichtbar sind, aber die Position der Kamera ändert nicht die Position von Objekten im Weltraum.
Kameras und Projektionen
Entwickler, die in 2D arbeiten, sind daran gewöhnt, Zeichnungsgrundtypen auf einem zweidimensionalen Bildschirm zu positionieren. Wenn Sie eine 3D-Szene erstellen, ist es wichtig zu beachten, dass Sie wirklich eine 2D-Darstellung von 3D-Objekten erstellen. Da eine 3D-Szene je nach Blickpunkt anders aussieht, müssen Sie diesen Standpunkt angeben. Mit Camera der Klasse können Sie diesen Standpunkt für eine 3D-Szene angeben.
Eine weitere Möglichkeit, zu verstehen, wie eine 3D-Szene auf einer 2D-Oberfläche dargestellt wird, besteht darin, die Szene als Projektion auf der Anzeigeoberfläche zu beschreiben. Auf ProjectionCamera diese Weise können Sie verschiedene Projektionen und deren Eigenschaften angeben, um zu ändern, wie die 3D-Modelle des Betrachters angezeigt werden. Eine PerspectiveCamera spezifiziert eine Projektion, die die Szene verkürzt. Mit anderen Worten, die PerspectiveCamera bietet eine Fluchtpunktperspektive. Sie können die Position der Kamera im Koordinatenbereich der Szene, die Richtung und das Sichtfeld für die Kamera sowie einen Vektor angeben, der die Richtung "nach oben" in der Szene definiert. Das folgende Diagramm veranschaulicht die PerspectiveCameraProjektion.
Die NearPlaneDistance und FarPlaneDistance Eigenschaften von ProjectionCamera begrenzen den Bereich der Kameraprojektion. Da Kameras an einer beliebigen Stelle in der Szene positioniert werden können, ist es möglich, dass die Kamera tatsächlich innerhalb eines Modells oder sehr in der Nähe eines Modells positioniert werden kann, wodurch es schwierig ist, Objekte richtig zu unterscheiden. NearPlaneDistance ermöglicht es Ihnen, einen Mindestabstand von der Kamera anzugeben, über den Objekte nicht gezeichnet werden. Umgekehrt können Sie einen Abstand von der Kamera angeben, ab welchem Punkt FarPlaneDistance Objekte nicht gezeichnet werden. Das stellt sicher, dass Objekte, die zu weit entfernt sind, um erkannt zu werden, nicht in die Szene einbezogen werden.
Kameraposition
OrthographicCamera Gibt eine orthogonale Projektion eines 3D-Modells auf eine 2D-visuelle Oberfläche an. Wie andere Kameras gibt sie eine Position, Sichtrichtung und "nach oben"-Richtung an. Im Gegensatz zu PerspectiveCamera beschreibt OrthographicCamera jedoch eine Projektion, die keine perspektivische Verzerrung enthält. Mit anderen Worten beschreibt OrthographicCamera ein Anzeigefeld, dessen Seiten parallel sind, anstatt eines, dessen Seiten sich in einem Punkt an der Kamera treffen. Die folgende Abbildung zeigt das gleiche Modell wie bei verwendung PerspectiveCamera und OrthographicCamera.
Perspektivische und orthografische Projektionen
Der folgende Code zeigt einige typische Kameraeinstellungen.
// 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- und Mesh-Primitiven
Model3D ist die abstrakte Basisklasse, die ein generisches 3D-Objekt darstellt. Zum Erstellen einer 3D-Szene benötigen Sie einige Objekte zur Anzeige, und die Objekte, aus denen der Szenengraph besteht, stammen von Model3D. Derzeit unterstützt das WPF modellierungsgeometrien mit GeometryModel3D. Die Geometry-Eigenschaft dieses Modells erfordert eine Mesh-Primitive.
Um ein Modell zu erstellen, beginnen Sie, indem Sie zunächst ein Primitiv oder ein Gitter erstellen. Ein 3D-Primitiv ist eine Sammlung von Scheitelpunkten, die eine einzige 3D-Entität bilden. Die meisten 3D-Systeme bieten Grundtypen, die auf der einfachsten geschlossenen Abbildung modelliert sind: ein Dreieck, das durch drei Scheitelpunkte definiert ist. Da die drei Punkte eines Dreiecks koplanar sind, können Sie mit dem Hinzufügen von Dreiecken fortfahren, um komplexere Formen zu modellieren, die als Gitter bezeichnet werden.
Das WPF 3D-System stellt derzeit die MeshGeometry3D Klasse bereit, mit der Sie jede Geometrie festlegen können; es unterstützt derzeit keine vordefinierten 3D-Primitiven wie Kugeln und kubische Formen. Beginnen Sie mit dem Erstellen, indem Sie eine Liste von Dreiecksecken als MeshGeometry3D Eigenschaft angeben. Jeder Scheitelpunkt wird als ein Point3D. (Geben Sie in XAML diese Eigenschaft als eine Liste von Zahlen an, die in Dreien gruppiert sind und die Koordinaten der einzelnen Eckpunkte darstellen.) Je nach Geometrie kann das Mesh aus vielen Dreiecken bestehen, von denen einige dieselben Eckpunkte (Vertizes) teilen. Um das Gitter richtig zu zeichnen, benötigt das WPF Informationen darüber, welche Scheitelpunkte von welchen Dreiecken gemeinsam verwendet werden. Sie geben diese Informationen an, indem Sie eine Liste von Dreiecksindizes mit der TriangleIndices Eigenschaft angeben. Diese Liste gibt die Reihenfolge an, in der die in der Positions Liste angegebenen Punkte ein Dreieck bestimmen.
<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>
Im vorherigen Beispiel gibt die Positions Liste vier Scheitelpunkte an, um ein Rechteckgitter zu definieren. Die TriangleIndices Eigenschaft gibt eine Liste von zwei Gruppen von drei Indizes an. Jede Zahl in der Liste bezieht sich auf einen Offset in der Positions Liste. Beispielsweise sind die ersten drei Scheitelpunkte, die durch die Positions Liste angegeben werden (-1,-1,0), (1,-1,0)und (-1,1,0). Die ersten drei in der TriangleIndices Liste angegebenen Indizes sind 0, 1 und 2, die den ersten, zweiten und dritten Punkten in der Positions Liste entsprechen. Daher wird das erste Dreieck, aus dem das Rechteckmodell besteht, von (-1,-1,0) bis zu (1,-1,0)(-1,1,0)zusammengesetzt, und das zweite Dreieck wird ähnlich bestimmt.
Sie können das Modell weiter definieren, indem Sie Werte für die Normals und TextureCoordinates Eigenschaften angeben. Um die Oberfläche des Modells zu rendern, benötigt das Grafiksystem Informationen dazu, in welche Richtung sich die Oberfläche in einem beliebigen Dreieck befindet. Es verwendet diese Informationen, um Beleuchtungsberechnungen für das Modell zu erstellen: Oberflächen, die sich direkt in Richtung einer Lichtquelle befinden, erscheinen heller als diejenigen, die vom Licht abgewinkelt sind. Obwohl der WPF standardnormale Vektoren mithilfe der Positionskoordinaten bestimmen kann, können Sie auch unterschiedliche normale Vektoren angeben, um die Darstellung gekrümmter Oberflächen anzunähern.
Die TextureCoordinates-Eigenschaft gibt eine Auflistung von Pointn an, die dem Grafiksystem mitteilen, wie die Koordinaten zugewiesen werden, die bestimmen, wie eine Textur auf die Ecken des Gitters gezeichnet wird. TextureCoordinates werden als Wert zwischen Null und 1 (einschließlich) angegeben. Wie bei der Normals-Eigenschaft kann das Grafiksystem Standardtextkoordinaten berechnen, Sie können jedoch auch andere Textkoordinaten festlegen, um die Zuordnung einer Textur zu steuern, die z. B. einen Teil eines wiederholten Musters enthält. Weitere Informationen zu Texturkoordinaten finden Sie in nachfolgenden Themen oder im Managed Direct3D SDK.
Das folgende Beispiel zeigt, wie Sie eine Oberfläche des Cubemodells im prozeduralen Code erstellen. Sie können den gesamten Würfel als ein einziges GeometryModel3D zeichnen; in diesem Beispiel wird die Fläche des Würfels als separates Modell gezeichnet, um später separate Texturen auf jede Fläche anzuwenden.
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))
Anwenden von Materialien auf das Modell
Damit ein Gitter wie ein dreidimensionales Objekt aussieht, muss es über eine angewendete Textur verfügen, um die oberfläche abzudecken, die durch ihre Scheitelpunkte und Dreiecke definiert ist, damit es von der Kamera beleuchtet und projiziert werden kann. In 2D verwenden Sie die Brush Klasse, um Farben, Muster, Farbverläufe oder andere visuelle Inhalte auf Bereiche des Bildschirms anzuwenden. Das Erscheinungsbild von 3D-Objekten ist jedoch eine Funktion des Beleuchtungsmodells, nicht nur der Farbe oder des Musters, die auf sie angewendet werden. Reale Objekte spiegeln Licht je nach Qualität ihrer Oberflächen unterschiedlich wider: Glänzende und glänzende Oberflächen sehen nicht wie raue oder matte Oberflächen aus, und einige Objekte scheinen Licht zu absorbieren, während andere leuchten. Sie können alle gleichen Pinsel auf 3D-Objekte anwenden, die Sie auf 2D-Objekte anwenden können, sie können jedoch nicht direkt angewendet werden.
Um die Merkmale der Oberfläche eines Modells zu definieren, verwendet WPF die Material abstrakte Klasse. Die konkreten Unterklassen von Material bestimmen einige der Darstellungsmerkmale der Oberfläche des Modells, und jede stellt eine Brush-Eigenschaft bereit, an die Sie einen SolidColorBrush, TileBrush oder VisualBrush übergeben können.
DiffuseMaterial Gibt an, dass der Pinsel auf das Modell angewendet wird, als ob dieses Modell diffus beleuchtet wurde. Die Verwendung von DiffuseMaterial ähnelt am ehesten der Verwendung von Pinseln direkt auf 2D-Modellen; Modelloberflächen spiegeln das Licht nicht so wider, als wäre es glänzender.
SpecularMaterial Gibt an, dass der Pinsel auf das Modell angewendet wird, als ob die Oberfläche des Modells hart oder glänzend wäre und in der Lage, Lichtreflexe zu spiegeln. Sie können den Grad festlegen, in dem die Textur diese reflektierende Qualität oder "Glanz" vorschlagen wird, indem Sie einen Wert für die SpecularPower Eigenschaft angeben.
EmissiveMaterial ermöglicht es Ihnen, anzugeben, dass die Textur angewendet wird, als ob das Modell Licht ausgibt, das der Farbe des Pinsels entspricht. Dies macht das Modell nicht zu einem Licht; Sie nimmt jedoch anders an der Schattierung teil, als wenn sie mit DiffuseMaterial oder SpecularMaterial texturiert würde.
Um eine bessere Leistung zu erzielen, werden die Rückseiten eines GeometryModel3D (die Flächen, die aufgrund ihrer Lage auf der gegenüberliegenden Seite des Modells von der Kamera nicht sichtbar sind) aus der Szene entfernt. Wenn Sie einen Material Wert angeben möchten, der auf die Rückseite eines Modells wie eine Ebene angewendet werden soll, legen Sie die Eigenschaft des BackMaterial Modells fest.
Um einige Oberflächenqualitäten wie Leuchteffekte oder reflektierende Effekte zu erzielen, sollten Sie mehrere verschiedene Pinsel nacheinander auf ein Modell anwenden. Sie können mehrere Materialien mithilfe der MaterialGroup Klasse anwenden und wiederverwenden. Die Kinder der MaterialGroup werden in mehreren Rendering-Durchläufen von zuerst bis zuletzt angewendet.
Die folgenden Codebeispiele zeigen, wie Sie eine Volltonfarbe und eine Zeichnung als Pinsel auf 3D-Modelle anwenden.
<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))
Beleuchtung der Szene
Licht in 3D-Grafiken tun, was Lichter in der realen Welt tun: Sie machen Oberflächen sichtbar. Genauer gesagt bestimmen die Lichter, welcher Teil einer Szene in die Projektion einbezogen wird. Lichtobjekte in WPF erzeugen eine Vielzahl von Licht- und Schatteneffekten und werden nach dem Verhalten verschiedener realen Lichter modelliert. Schließen Sie mindestens ein Licht in Ihre Szene ein, oder es sind keine Modelle sichtbar.
Die folgenden Lichter werden von der Basisklasse Lightabgeleitet:
AmbientLight: Bietet Umgebungsbeleuchtung, die alle Objekte unabhängig von ihrer Position oder Ausrichtung einheitlich beleuchtet.
DirectionalLight: Leuchtet wie eine fern liegende Lichtquelle. Richtungslichter haben eine Direction, die als Vector3D angegeben ist, aber keinen angegebenen Ort.
PointLight: Leuchtet wie eine nahe Lichtquelle. PointLights haben eine Position und werfen Licht von dieser Position aus. Objekte in der Szene werden je nach Position und Abstand im Hinblick auf das Licht beleuchtet. PointLightBase macht eine Range Eigenschaft verfügbar, die eine Entfernung bestimmt, über die Modelle nicht durch das Licht beleuchtet werden. PointLight macht auch Dämpfungseigenschaften verfügbar, die bestimmen, wie die Intensität des Lichts im Abstand abnimmt. Sie können konstante, lineare oder quadratische Interpolationsarten für die Abschwächung des Lichts festlegen.
SpotLight: Erbt von PointLight. Spotlights leuchten wie PointLight und weisen sowohl Position als auch Richtung auf. Sie projizieren Licht in einem kegelförmigen Bereich, der von InnerConeAngle und OuterConeAngle Eigenschaften festgelegt wird, die in Grad angegeben sind.
Lichter sind Model3D Objekte, sodass Sie Lichteigenschaften wie Position, Farbe, Richtung und Bereich transformieren und animieren können.
<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)
Transformieren von Modellen
Wenn Sie Modelle erstellen, haben sie eine bestimmte Position in der Szene. Um diese Modelle in der Szene zu verschieben, sie zu drehen oder ihre Größe zu ändern, ist es nicht praktisch, die Scheitelpunkte zu ändern, die die Modelle selbst definieren. Stattdessen wenden Sie Transformationen wie in 2D auf Modelle an.
Jedes Modellobjekt verfügt über eine Transform Eigenschaft, mit der Sie das Modell verschieben, neu ausrichten oder dessen Größe ändern können. Wenn Sie eine Transformation anwenden, werden alle Punkte des Modells effektiv durch den Vektor oder Wert, der von der Transformation angegeben wird, versetzt. Mit anderen Worten, Sie haben den Koordinatenbereich transformiert, in dem das Modell definiert ist ("Modellraum"), aber Sie haben die Werte, aus denen die Geometrie des Modells besteht, im Koordinatensystem der gesamten Szene ("Weltraum") nicht geändert.
Weitere Informationen zum Transformieren von Modellen finden Sie in der Übersicht über 3D-Transformationen.
Animieren von Modellen
Die WPF 3D-Implementierung nimmt am gleichen Timing- und Animationssystem wie 2D-Grafiken teil. Mit anderen Worten: Um eine 3D-Szene zu animieren, animieren Sie die Eigenschaften ihrer Modelle. Es ist möglich, Eigenschaften von Grundtypen direkt zu animieren, aber in der Regel ist es einfacher, Transformationen zu animieren, die die Position oder Darstellung von Modellen ändern. Da Transformationen sowohl auf Model3DGroup Objekte als auch auf einzelne Modelle angewendet werden können, ist es möglich, eine Gruppe von Animationen auf ein untergeordnetes Element einer Model3DGroup und eine andere Gruppe von Animationen auf eine Gruppe untergeordneter Objekte anzuwenden. Sie können auch eine Vielzahl visueller Effekte erzielen, indem Sie die Eigenschaften der Beleuchtung Ihrer Szene animieren. Schließlich können Sie die Projektion selbst animieren, indem Sie die Kameraposition oder das Sichtfeld animieren. Hintergrundinformationen zum WPF-Zeiten- und Animationssystem finden Sie in den Themen "Übersicht über Animation", "Übersicht über Storyboards" und "Übersicht über einfrierbare Objekte".
Um ein Objekt in WPF zu animieren, erstellen Sie eine Zeitachse, definieren eine Animation (die im Laufe der Zeit eine Änderung des Eigenschaftswerts ist), und geben Sie die Eigenschaft an, auf die die Animation angewendet werden soll. Da alle Objekte in einer 3D-Szene Kinder von Viewport3D sind, sind die Eigenschaften, die jede Animation, die Sie auf die Szene anwenden möchten, zum Ziel hat, Eigenschaften von Viewport3D.
Angenommen, Sie möchten ein Modell so gestalten, dass es an Ort und Stelle wackelt. Sie könnten ein RotateTransform3D auf das Modell anwenden und die Achse seiner Drehung von einem Vektor zum anderen animieren. Das folgende Codebeispiel veranschaulicht das Anwenden einer Vector3DAnimation auf die Axis-Eigenschaft der Rotation3D. Es wird angenommen, dass RotateTransform3D eine der mehreren Transformationen ist, die in einer TransformGroup auf das Modell angewendet werden.
//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)
Hinzufügen von 3D-Inhalten zum Fenster
Um die Szene zu rendern, fügen Sie Modelle und Lichter zu einem Model3DGroup hinzu, und legen Sie dann das Model3DGroup als Content eines ModelVisual3D fest. Fügen Sie ModelVisual3D der Children-Sammlung des Viewport3D hinzu. Fügen Sie Kameras dem Viewport3D hinzu, indem Sie deren Camera Eigenschaft festlegen.
Fügen Sie schließlich Viewport3D dem Fenster hinzu. Wenn der Viewport3D als Inhalt eines Layoutelements wie Canvas enthalten ist, geben Sie die Größe des Viewport3D an, indem Sie dessen Height- und Width-Eigenschaften festlegen (geerbt von 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>
Siehe auch
.NET Desktop feedback