Panoramica della grafica 3D

La funzionalità 3D in Windows Presentation Foundation (WPF) consente agli sviluppatori di disegnare, trasformare e animare grafica 3D sia nel markup che nel codice procedurale. Gli sviluppatori possono combinare grafica 2D e 3D per creare controlli avanzati, fornire illustrazioni complesse dei dati o migliorare l'esperienza utente dell'interfaccia di un'applicazione. Il supporto 3D in WPF non è progettato per offrire una piattaforma di sviluppo di giochi completa. In questo argomento viene fornita una panoramica delle funzionalità 3D nel sistema grafico WPF.

3D in un contenitore 2D

Il contenuto grafico 3D in WPF viene incapsulato in un elemento , Viewport3D, che può partecipare alla struttura di elementi bidimensionali. Il sistema grafico considera Viewport3D come un elemento visivo bidimensionale come molti altri in WPF. Viewport3D funge da finestra, ovvero un viewport, in una scena tridimensionale. In modo più accurato, si tratta di una superficie su cui viene proiettata una scena 3D.

In un'applicazione 2D convenzionale usare Viewport3D come un altro elemento contenitore, ad esempio Grid o Canvas. Sebbene sia possibile usare Viewport3D con altri oggetti di disegno 2D nello stesso grafico della scena, non è possibile interpenetrate oggetti 2D e 3D all'interno di un oggetto Viewport3D. In questo argomento verrà illustrato come disegnare grafica 3D all'interno di Viewport3D.

Spazio coordinate 3D

Il sistema di coordinate WPF per la grafica 2D individua l'origine nell'angolo superiore sinistro dell'area di rendering (in genere lo schermo). Nel sistema 2D, i valori positivi dell'asse x procedono verso destra e i valori positivi dell'asse y procedono verso il basso. Nel sistema di coordinate 3D, tuttavia, l'origine si trova al centro dell'area di rendering, con valori positivi dell'asse x che procede verso destra ma i valori positivi dell'asse y procedendo verso l'alto e i valori positivi dell'asse z che procedono verso l'esterno dall'origine, verso il visualizzatore.

Coordinate systems
Rappresentazioni convenzionali del sistema di coordinate 2D e 3D

Lo spazio definito da questi assi è la cornice di riferimento fissa per gli oggetti 3D in WPF. Quando si compilano modelli in questo spazio e si creano luci e fotocamere per visualizzarli, è consigliabile distinguere il fotogramma di riferimento fisso, o "spazio globale", da quello di riferimento locale creato per ogni modello quando si applicano trasformazioni. Si ricordi anche che gli oggetti dello spazio globale possono avere un aspetto completamente diverso o non essere completamente visibili, a seconda delle impostazioni di luce e fotocamera e che la posizione della fotocamera tuttavia non modifica la posizione degli oggetti nello spazio globale.

Fotocamere e proiezioni

Gli sviluppatori che lavorano in 2D sono abituati a posizionare primitive di disegno su uno schermo bidimensionale. Quando crei una scena 3D, è importante ricordare che stai davvero creando una rappresentazione 2D di oggetti 3D. Poiché una scena 3D ha un aspetto diverso a seconda del punto di vista dello sguardo, è necessario specificare tale punto di vista. La Camera classe consente di specificare questo punto di visualizzazione per una scena 3D.

Un altro modo per comprendere come una scena 3D è rappresentata su una superficie 2D descrivendo la scena come proiezione sulla superficie di visualizzazione. ProjectionCamera Consente di specificare proiezioni diverse e le relative proprietà per modificare la modalità di visualizzazione dei modelli 3D da parte del pubblico. Specifica PerspectiveCamera una proiezione che foresorta la scena. In altre parole, fornisce PerspectiveCamera una prospettiva punto di fuga. È possibile specificare la posizione della fotocamera nello spazio delle coordinate della scena, la direzione e il campo visivo per la fotocamera, nonché un vettore che definisce la direzione verso l'alto nella scena. Il diagramma seguente illustra la PerspectiveCameraproiezione.

Le NearPlaneDistance proprietà e FarPlaneDistance di ProjectionCamera limitano l'intervallo della proiezione della fotocamera. Poiché le fotocamere possono trovarsi in qualsiasi punto della scena, è possibile che la fotocamera venga posizionata all'interno di un modello o accanto al modello stesso, rendendo difficile distinguere in modo corretto gli oggetti. NearPlaneDistance consente di specificare una distanza minima dalla fotocamera oltre la quale gli oggetti non verranno disegnati. Al contrario, FarPlaneDistance consente di specificare una distanza dalla fotocamera oltre la quale gli oggetti non verranno disegnati, in modo da garantire che gli oggetti troppo lontani non siano riconoscibili nella scena.

Camera setup
Posizione della fotocamera

OrthographicCamera specifica una proiezione ortogonale di un modello 3D in una superficie visiva 2D. In modo analogo ad altre fotocamere, l'oggetto specifica una posizione, una direzione di visualizzazione e una direzione verso l'alto. A differenza di PerspectiveCamera, tuttavia, OrthographicCamera descrive una proiezione che non include la prospettiva di foreshortening. In altre parole, OrthographicCamera descrive un riquadro di visualizzazione i cui lati sono paralleli, anziché uno i cui lati si incontrano in un punto della fotocamera. L'immagine seguente mostra lo stesso modello visualizzato usando PerspectiveCamera e OrthographicCamera.

Orthographic and perspective projection
Proiezioni prospettiche e ortografiche

Il codice seguente illustra alcune impostazioni tipiche della fotocamera.

// 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

Modello e primitive mesh

Model3D è la classe base astratta che rappresenta un oggetto 3D generico. Per creare una scena 3D, sono necessari alcuni oggetti da visualizzare e gli oggetti che costituiscono il grafico della scena derivano da Model3D. Attualmente, WPF supporta geometrie di modellazione con GeometryModel3D. La Geometry proprietà di questo modello accetta una primitiva mesh.

Per compilare un modello, iniziare a compilare una primitiva (o mesh). Una primitiva 3D è una raccolta di vertici che formano una singola entità 3D. La maggior parte dei sistemi 3D fornisce primitive modellate sulla figura chiusa più semplice: un triangolo definito da tre vertici. Poiché i tre punti di un triangolo sono complanari, è possibile continuare ad aggiungere triangoli per modellare forme più complesse, denominate mesh.

Il sistema WPF 3D attualmente fornisce la MeshGeometry3D classe , che consente di specificare qualsiasi geometria; attualmente non supporta primitive 3D predefinite come sfere e forme cubiche. Iniziare a creare un MeshGeometry3D oggetto specificando un elenco di vertici di triangoli come proprietà Positions . Ogni vertice viene specificato come .Point3D In XAML specificare questa proprietà come elenco di numeri raggruppati in tre che rappresentano le coordinate di ogni vertice. A seconda della geometria, la mesh potrebbe essere composta da molti triangoli, alcuni dei quali condividono gli stessi angoli (vertici). Per disegnare correttamente la mesh, WPF necessita di informazioni sui vertici condivisi da quali triangoli. Per fornire queste informazioni, specificare un elenco di indici di triangoli con la TriangleIndices proprietà . Questo elenco specifica l'ordine in cui i punti specificati nell'elenco Positions determineranno un triangolo.

<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>

Nell'esempio precedente l'elenco Positions specifica quattro vertici per definire una mesh rettangolo. La TriangleIndices proprietà specifica un elenco di due gruppi di tre indici. Ogni numero nell'elenco fa riferimento a un offset nell'elenco Positions . Ad esempio, i primi tre vertici specificati dall'elenco Positions sono (-1,-1,0), (1,-1,0)e (-1,1,0). I primi tre indici specificati dall'elenco TriangleIndices sono 0, 1 e 2, che corrispondono al primo, secondo e terzo punto dell'elenco Positions . Di conseguenza, il primo triangolo che costituisce il modello rettangolo sarà composto da (-1,-1,0) a (1,-1,0)(-1,1,0)e , e il secondo triangolo verrà determinato in modo analogo.

È possibile continuare a definire il modello specificando i valori per le Normals proprietà e TextureCoordinates . Per eseguire il rendering della superficie del modello, è necessario che il sistema grafico disponga delle informazioni per stabilire la direzione verso cui è rivolta la superficie in corrispondenza di tutti i triangoli specificati. Tali informazioni consentono al sistema di eseguire calcoli di illuminazione per il modello, con le superfici rivolte direttamente verso una sorgente di luce più brillanti rispetto a quelle con angolazione rispetto alla luce. Anche se WPF può determinare i vettori normali predefiniti usando le coordinate di posizione, è anche possibile specificare vettori normali diversi per approssimare l'aspetto delle superfici curve.

La TextureCoordinates proprietà specifica una raccolta di Pointoggetti che indicano al sistema grafico come eseguire il mapping delle coordinate che determinano il modo in cui una trama viene disegnata ai vertici della mesh. TextureCoordinates vengono specificati come valore compreso tra zero e 1, inclusi. Come per la Normals proprietà , il sistema grafico può calcolare le coordinate di trama predefinite, ma è possibile scegliere di impostare coordinate di trama diverse per controllare il mapping di una trama che include parte di un pattern ripetuto, ad esempio. Per altre informazioni sulle coordinate di trama, vedere gli argomenti successivi oppure Managed Direct3D SDK.

L'esempio seguente illustra come creare una faccia del modello di cubo in codice procedurale. È possibile disegnare l'intero cubo come singolo GeometryModel3D. In questo esempio viene disegnato il viso del cubo come modello distinto per applicare trame separate a ogni viso in un secondo momento.

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))

'

Applicazione di classi Material al modello

Affinché assuma l'aspetto di oggetto tridimensionale, è necessario che a una mesh venga applicata una trama per coprire la superficie definita dai relativi vertici e triangoli, in modo che possa essere illuminata e proiettata dalla fotocamera. In 2D si usa la Brush classe per applicare colori, modelli, sfumature o altro contenuto visivo alle aree dello schermo. L'aspetto degli oggetti 3D, tuttavia, è una funzione del modello di illuminazione, non solo del colore o del motivo applicato. Gli oggetti reali riflettono la luce in modo diverso in base alla qualità delle superfici. Le superfici lucide e brillanti non presentano infatti lo stesso aspetto delle superfici grezze o opache e alcuni oggetti sembrano assorbire la luce, mentre altri la riflettono. Puoi applicare tutti gli stessi pennelli a oggetti 3D che puoi applicare agli oggetti 2D, ma non puoi applicarli direttamente.

Per definire le caratteristiche della superficie di un modello, WPF usa la Material classe astratta. Le sottoclassi concrete della classe Material determinano alcune caratteristiche di aspetto della superficie del modello e a ognuna è associata anche una proprietà Brush a cui è possibile passare un oggetto SolidColorBrush, TileBrush o VisualBrush.

  • DiffuseMaterial specifica che il pennello verrà applicato al modello come se il modello fosse acceso in modo diffuso. L'uso di DiffuseMaterial è molto simile all'uso di pennelli direttamente su modelli 2D; le superfici del modello non riflettono la luce come se fosse brillante.

  • SpecularMaterial specifica che il pennello verrà applicato al modello come se la superficie del modello fosse dura o lucida, in grado di riflettere le evidenziazioni. È possibile impostare il grado in cui la trama suggerisce questa qualità riflettente o "brillare", specificando un valore per la SpecularPower proprietà.

  • EmissiveMaterial consente di specificare che la trama verrà applicata come se il modello emettesse luce uguale al colore del pennello. In questo modo il modello non viene trasformato in luce ma partecipa in modo diverso all'applicazione di ombreggiatura rispetto a quanto accade nel caso di trama applicata con DiffuseMaterial o SpecularMaterial.

Per prestazioni migliori, i retroface di un oggetto GeometryModel3D (i volti che non sono visibili perché si trovano sul lato opposto del modello dalla fotocamera) vengono rimossi dalla scena. Per specificare un Material oggetto da applicare al backface di un modello come un piano, impostare la proprietà del BackMaterial modello.

Per ottenere alcune qualità della superficie, ad esempio l'effetto alone o riflettente, è necessario applicare a un modello più pennelli diversi in successione. È possibile applicare e riutilizzare più materiali usando la MaterialGroup classe . Gli elementi figlio di MaterialGroup vengono applicati dal primo all'ultimo in più passaggi di rendering.

Gli esempi di codice seguenti illustrano come applicare un colore a tinta unita e un disegno come pennelli ai modelli 3D.

<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))

Illuminazione della scena

Le luci nella grafica 3D fanno ciò che le luci fanno nel mondo reale: rendono visibili le superfici. Più precisamente, le luci determinano la parte di scena che viene inclusa nella proiezione. Gli oggetti luce in WPF creano una varietà di effetti luce e ombreggiatura e vengono modellati dopo il comportamento di varie luci reali. Includere almeno una luce nella scena o nessun modello sarà visibile.

Le luci seguenti derivano dalla classe Lightbase :

  • AmbientLight: fornisce un'illuminazione ambientale che illumina tutti gli oggetti in modo uniforme indipendentemente dalla posizione o dall'orientamento.

  • DirectionalLight: illumina come una sorgente di luce distante. Le luci direzionali hanno un Direction oggetto specificato come Vector3D, ma nessuna posizione specificata.

  • PointLight: illumina come una sorgente di luce vicina. Agli oggetti PointLights è associata una posizione dalla quale proiettano la luce. Gli oggetti nella scena vengono illuminati in base alla posizione e alla distanza rispetto alla luce. PointLightBase espone una Range proprietà, che determina una distanza oltre la quale i modelli non verranno illuminati dalla luce. PointLight espone anche le proprietà di attenuazione, che determinano il modo in cui l'intensità della luce diminuisce sulla distanza. Per l'attenuazione della luce, è possibile specificare interpolazioni costanti, lineari o quadratiche.

  • SpotLight: eredita da PointLight. Gli oggetti Spotlight illuminano come gli oggetti PointLight, dispongono di posizione e direzione Proiettano la luce in un'area a forma di cono impostata da InnerConeAngle proprietà e OuterConeAngle specificate in gradi.

Le luci sono Model3D oggetti, in modo da poter trasformare e animare le proprietà della luce, tra cui posizione, colore, direzione e intervallo.

<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)

Trasformazione di modelli

Quando vengono creati, i modelli hanno una determinata posizione nella scena. Per spostare i modelli nella scena, ruotarli o modificarne la dimensione, non è pratico modificare i vertici che li definiscono, Al contrario, proprio come in 2D, si applicano trasformazioni ai modelli.

Ogni oggetto modello ha una Transform proprietà con cui è possibile spostare, riorientare o ridimensionare il modello. Quando si applica una trasformazione, si esegue in effetti l'offset di tutti i punti del modello in base a qualsiasi vettore o valore specificato dalla trasformazione. In altre parole, viene trasformato lo spazio delle coordinate in cui il modello è definito ("spazio modello"), ma non vengono modificati i valori che costituiscono la geometria del modello nel sistema di coordinate dell'intera scena ("spazio globale").

Per altre informazioni sulla trasformazione dei modelli, vedere Cenni preliminari sulle trasformazioni 3D.

Animazione di modelli

L'implementazione 3D di WPF partecipa allo stesso sistema di temporizzazione e animazione della grafica 2D. In altre parole, per animare una scena 3D, animare le proprietà dei relativi modelli. Anche se è possibile animare direttamente proprietà di primitive, in genere è più semplice animare trasformazioni che modificano la posizione o l'aspetto di modelli. Poiché le trasformazioni possono essere applicate a Model3DGroup oggetti e a singoli modelli, è possibile applicare un set di animazioni a un elemento figlio di model3DGroup e a un altro set di animazioni a un gruppo di oggetti figlio. È possibile anche realizzare numerosi effetti visivi animando le proprietà di illuminazione della scena. È infine possibile scegliere di animare la proiezione stessa animando la posizione della fotocamera o il campo visivo. Per informazioni di base sul sistema di temporizzazione e animazione WPF, vedere gli argomenti Cenni preliminari sull'animazione, Cenni preliminari sugli storyboard e Cenni preliminari sugli oggetti Freezable.

Per animare un oggetto in WPF, crea una sequenza temporale, definisci un'animazione (che in realtà è una modifica di un valore della proprietà nel tempo) e specifichi la proprietà a cui applicare l'animazione. Poiché tutti gli oggetti in una scena 3D sono elementi figlio di Viewport3D, le proprietà di destinazione di qualsiasi animazione da applicare alla scena sono proprietà di Viewport3D.

Si supponga di voler creare un modello in grado di oscillare sul posto. È possibile scegliere di applicare un RotateTransform3D oggetto al modello e animare l'asse della rotazione da un vettore a un altro. L'esempio di codice seguente illustra l'applicazione di un oggetto Vector3DAnimation alla proprietà Axis dell'oggetto Rotation3D della trasformazione, presupponendo che RotateTransform3D sia una delle diverse trasformazioni applicate al modello con un oggetto 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)

Aggiungere contenuto 3D alla finestra

Per eseguire il rendering della scena, aggiungere modelli e luci a un Model3DGroupoggetto , quindi impostare come Model3DGroup di Content un oggetto ModelVisual3D. Aggiungere all'insieme ModelVisual3DChildren dell'oggetto Viewport3D. Aggiungere fotocamere a Viewport3D impostandone la Camera proprietà.

Infine, aggiungere l'oggetto Viewport3D alla finestra. Viewport3D Quando viene incluso come contenuto di un elemento di layout come Canvas, specificare le dimensioni di Viewport3D impostandone Height le proprietà e Width (ereditate da 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>

Vedi anche