Información general sobre gráficos 3D

La funcionalidad de 3-D en Windows Presentation Foundation (WPF) permite a los desarrolladores dibujar, transformar y animar gráficos 3D en el marcado y en el código de procedimiento. Los desarrolladores pueden combinar gráficos 2-D y 3-D para crear controles enriquecidos, proporcionar ilustraciones complejas de datos o mejorar la experiencia del usuario de la interfaz de una aplicación. La compatibilidad con 3-D en WPF no se ha diseñado para proporcionar una plataforma completa de desarrollo de juegos. En este tema se proporciona información general sobre la funcionalidad de 3-D en el sistema de gráficos de WPF.

Este tema contiene las secciones siguientes.

  • 3D en un contenedor 2D
  • Espacio de coordenadas 3D
  • Cámaras y proyecciones
  • Elementos primitivos de modelo y de malla
  • Aplicar materiales al modelo
  • Iluminar la escena
  • Transformar modelos
  • Animar modelos
  • Agregar contenido 3D a la ventana
  • Temas relacionados

3D en un contenedor 2D

El contenido de los gráficos 3-D de WPF se encapsula en un elemento, Viewport3D, que puede participar en la estructura de elementos bidimensionales. El sistema de gráficos trata los objetos Viewport3D como elementos visuales bidimensionales, al igual que ocurre con muchos otros elementos de WPF. Viewport3D funciona como una ventana (una ventanilla) de una escena tridimensional. Expresado de modo más preciso, es la superficie sobre la que se proyecta una escena 3-D.

En una aplicación 2-D convencional, utilice Viewport3D como cualquier otro elemento contenedor, como Grid o Canvas. Aunque puede utilizar Viewport3D con otros objetos de dibujo 2-D en el mismo gráfico de escena, no puede interpenetrar objetos 2-D y 3-D dentro de Viewport3D. Este tema se centrará en cómo dibujar gráficos 3-D dentro de Viewport3D.

Espacio de coordenadas 3D

El sistema de coordenadas de WPF para gráficos 2-D localiza el origen en la parte superior izquierda del área de representación (que suele ser la pantalla). En el sistema 2-D, los valores positivos del eje X se extienden hacia la derecha, y los valores positivos del eje Y extienden hacia abajo. En el sistema de coordenadas 3-D, sin embargo, el origen se encuentra en el centro del área de representación, los valores positivos del eje X se extienden hacia la derecha, los valores positivos del eje Y se extienden hacia arriba (no hacia abajo) y los valores positivos del eje Z se extienden hacia el exterior partiendo del origen, es decir, hacia el espectador.

Representaciones convencionales de los sistemas de coordenadas 2D y 3D

Sistemas de coordenadas

El espacio definido por estos ejes es el marco estático de referencia para los objetos 3-D en WPF. Cuando se generan modelos en este espacio y se crean luces y cámaras para verlos, resulta útil distinguir este marco estático de referencia, o "espacio universal", del marco de referencia local creado para cada modelo al aplicarle transformaciones. Recuerde también que los objetos del espacio universal podrían parecer completamente diferentes, o incluso no estar visibles en absoluto, dependiendo de la configuración de las luces y la cámara, pero que la posición de la cámara no cambia la ubicación de los objetos en el espacio universal.

Cámaras y proyecciones

Los programadores que trabajan en 2-D están acostumbrado a colocar los elementos de dibujo primitivos en una pantalla bidimensional. Al crear una escena 3-D, es importante recordar que, en realidad, se está creando una representación 2-D de los objetos 3-D. Dado que una escena 3-D tiene un aspecto diferente dependiendo del punto de vista del espectador, debe especificar ese punto de vista. La clase Camera permite especificar este punto de vista para una escena 3-D.

Otra manera de entender cómo se representa una escena 3-D en una superficie 2-D consiste en describir dicha escena como una proyección sobre la superficie de visualización. ProjectionCamera permite especificar proyecciones diferentes y sus propiedades para cambiar la manera en que el espectador ve los modelos 3-D. PerspectiveCamera especifica una proyección en escorzo de la escena. En otras palabras, PerspectiveCamera proporciona una perspectiva de punto de fuga. Puede especificar la posición de la cámara en el espacio de coordenadas de la escena, la dirección y el campo de visión de la cámara, y un vector que define la dirección "hacia arriba" en la escena. En el diagrama siguiente se muestra la proyección de PerspectiveCamera.

Las propiedades NearPlaneDistance y FarPlaneDistance de ProjectionCamera limitan el intervalo de proyección de la cámara. Dado que las cámaras se pueden ubicar en cualquier parte de la escena, es posible situarlas dentro de un modelo o muy cerca de él, con lo que resultaría difícil distinguir correctamente los objetos. NearPlaneDistance permite especificar una distancia mínima a la cámara a partir de la cual no se dibujarán objetos. A la inversa, FarPlaneDistance permite especificar una distancia máxima a la cámara, más allá de la que no se dibujarán objetos, lo que garantice que no se incluyan en la escena aquellos objetos que estén demasiado lejos para ser reconocibles.

Posición de la cámara

Instalación de cámara

OrthographicCamera especifica una proyección ortogonal de un modelo 3-D sobre una superficie visual 2-D. Al igual que otras cámaras, especifica una posición, dirección de visualización y dirección "hacia arriba". Sin embargo, a diferencia de PerspectiveCamera, OrthographicCamera describe una proyección que no incluye la perspectiva en escorzo. Es decir, OrthographicCamera describe un cuadro de vista cuyos lados son paralelos, en lugar de uno cuyos lados convergen en un punto de la cámara. La imagen siguiente muestra el mismo modelo visto con PerspectiveCamera y con OrthographicCamera.

Perspectiva y proyecciones ortográficas

Proyección en perspectiva y ortográfica

En el código siguiente se muestran algunos valores de cámara típicos.

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

Elementos primitivos de modelo y de malla

Model3D es la clase base abstracta que representa un objeto 3-D genérico. Para generar una escena 3-D, necesita algunos objetos que ver; los objetos que componen el gráfico de escena se derivan de la clase Model3D. En la actualidad, WPF permite geometrías de modelado con GeometryModel3D. La propiedad Geometry de este modelo acepta un elemento primitivo de malla.

Para crear un modelo, comience por crear un elemento primitivo, o malla. Un elemento 3-D primitivo es una colección de vértices que constituyen una entidad 3-D única. La mayoría de los sistemas 3-D proporcionan elementos primitivos modelados a partir de la figura cerrada más simple: un triángulo definido por tres vértices. Dado que los tres puntos de un triángulo son coplanares, puede seguir agregando triángulos para modelar formas más complejas, denominadas mallas.

El sistema 3-D de WPF proporciona actualmente la clase MeshGeometry3D, que permite especificar cualquier geometría; en este momento, no admite elementos 3-D primitivos predefinidos, tales como esferas o formas cúbicas. Empiece por crear MeshGeometry3D especificando una lista de vértices de triángulos como su propiedad Positions. Cada vértice se especifica como un Point3D. (En Extensible Application Markup Language (XAML), especifique esta propiedad como una lista de números agrupados en ternas, que representan las coordenadas de cada vértice.) Según cuál sea la geometría, la malla puede estar compuesta de muchos triángulos, algunos de los cuales compartirán las mismas esquinas (vértices). WPF necesita información sobre qué triángulos comparten qué vértices para dibujar la malla correctamente. Esta información se proporciona especificando una lista de índices de triángulos con la propiedad TriangleIndices. Esta lista especifica el orden en el que los puntos especificados en la lista Positions determinarán un triángulo.

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

En el ejemplo anterior, la lista Positions especifica ocho vértices para definir una malla en forma de cubo. La propiedad TriangleIndices especifica una lista de doce grupos de tres índices. Cada número de la lista hace referencia a un desplazamiento en la lista Positions. Por ejemplo, los tres primeros vértices especificados por la lista Positions son (1,1,0), (0,1,0) y (0,0,0). Los tres primeros índices especificados por la lista TriangleIndices son 0, 2 y 1, que corresponden a los puntos primero, tercero y segundo de la lista Positions. Como resultado, el primer triángulo que constituye el modelo del cubo se creará de (1,1,0) a (0,1,0) y a (0,0,0), y los once triángulos restantes se determinarán de igual forma.

Puede seguir definiendo el modelo especificando valores para las propiedades Normals y TextureCoordinates. Para representar la superficie del modelo, el sistema de gráficos necesita información sobre en qué dirección mira la superficie de cualquier triángulo dado. Utiliza esta información para realizar los cálculos de iluminación del modelo: las superficies que miran directamente hacia una fuente de luz parecen más luminosas que las que tienen un ángulo que las oculta de la luz. Aunque WPF puede determinar los vectores normales predeterminados utilizando las coordenadas de posición, también es posible especificar vectores normales diferentes para crear un aspecto más aproximado de las superficies curvas.

La propiedad TextureCoordinates especifica una colección de puntos (Point) que indica al sistema de gráficos cómo asignar las coordenadas que determinan cómo trazar una textura en los vértices de la malla. Las TextureCoordinates se especifican como un valor comprendido entre cero y 1, incluidos. Como sucede con la propiedad Normals, el sistema de gráficos puede calcular las coordenadas de textura predeterminadas, pero si lo desea puede establecer coordenadas de textura diferentes a fin de controlar la asignación de una textura que incluya parte de un patrón repetitivo, por ejemplo. Encontrará más información sobre coordenadas de textura en los temas siguientes o en Managed Direct3D SDK.

En el ejemplo siguiente se muestra cómo crear una cara del modelo del cubo en código de procedimiento. Observe que puede dibujar el cubo completo como un solo objeto GeometryModel3D; en este ejemplo se dibuja la cara del cubo como un modelo distinto a fin de aplicar después texturas independientes a cada cara.

        Private side1Plane As New MeshGeometry3D()
MeshGeometry3D side1Plane = 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));

Aplicar materiales al modelo

Para que una malla parezca un objeto tridimensional, debe tener una textura aplicada que cubra la superficie definida por sus vértices y triángulos, de manera que se pueda iluminar y proyectar por la cámara. En 2-D, se utiliza la clase Brush para aplicar colores, patrones, degradados y otro contenido visual a las áreas de la pantalla. El aspecto de los objetos 3-D, sin embargo, depende del modelo de iluminación, no sólo del color o del patrón que se les aplica. Los objetos reales reflejan la luz de manera distinta según la calidad de su superficie: las superficies satinadas y brillantes no tienen el mismo aspecto que las superficies ásperas o mates, y algunos objetos parecen absorber la luz, mientras que otros la emiten. Puede aplicar a los objetos 3-D los mismos pinceles que a los objetos 2-D, pero no directamente.

Para definir las características de la superficie de un modelo, WPF utiliza la clase abstracta Material. Las subclases concretas de Material determinan algunas de las características del aspecto de la superficie del modelo y, además, cada una de ellas proporciona una propiedad Brush a la que puede pasar SolidColorBrush, TileBrush o VisualBrush.

  • DiffuseMaterial especifica que el pincel se aplicará al modelo como si estuviera iluminado con una luz difusa. Utilizar DiffuseMaterial es lo que más se parece al uso directo de pinceles en los modelos 2-D; las superficies del modelo no reflejan la luz como si brillasen.

  • SpecularMaterial especifica que el pincel se aplicará al modelo como si la superficie del modelo fuese dura o brillante, capaz de reflejar la iluminación. Puede establecer el grado en que la textura sugerirá esta cualidad de reflexión, o "brillo", especificando un valor para la propiedad SpecularPower.

  • EmissiveMaterial permite especificar que la textura se aplicará como si el modelo estuviera emitiendo luz del mismo color que el pincel. Esto no convierte el modelo en una luz; sin embargo, participará de manera diferente en el sombreado que si se aplica textura con DiffuseMaterial o SpecularMaterial.

Para mejorar rendimiento, las caras ocultas de GeometryModel3D (aquéllas que están fuera de la vista porque se encuentran en el lado del modelo opuesto a la cámara) se seleccionan de la escena. Para especificar el Material que se aplicará a la cara oculta de un modelo, como un plano, establezca la propiedad BackMaterial del modelo.

Para lograr algunas cualidades de la superficie, como el brillo o los efectos de reflejo, puede ser conveniente aplicar sucesivamente varios pinceles diferentes a un modelo. Puede aplicar y reutilizar varios materiales mediante la clase MaterialGroup. Los elementos secundarios de MaterialGroup se aplican del primero al último en varias pasadas de representación.

En los ejemplos de código siguientes se muestra cómo aplicar un color sólido y un dibujo como pinceles a los modelos 3-D.

<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>
            Dim side5Material As New DiffuseMaterial(CType(Application.Current.Resources("patternBrush"), Brush))
DiffuseMaterial side5Material = new DiffuseMaterial((Brush)Application.Current.Resources["patternBrush"]);

Iluminar la escena

Las luces de los gráficos 3-D hacen lo mismo que las luces en el mundo real: permiten ver las superficies. Más concretamente, las luces determinan qué parte de una escena se incluye en la proyección. Los objetos de luz en WPF crean gran variedad de efectos de luz y sombra y siguen el modelo de comportamiento de diversas luces del mundo real. Debe incluir por lo menos una luz en la escena, pues de lo contrario no habrá ningún modelo visible.

Las luces siguientes se derivan de la clase base Light:

  • AmbientLight: proporciona iluminación de ambiente que ilumina uniformemente todos los objetos sin tener en cuenta su ubicación u orientación.

  • DirectionalLight: ilumina como una fuente de luz distante. Las luces direccionales tienen Direction, que se especifica como Vector3D, pero ninguna ubicación concreta.

  • PointLight: ilumina como una fuente de luz cercana. Las luces puntuales tienen posición y emiten la luz desde esa posición. Los objetos de la escena se iluminan dependiendo de su posición y distancia con respecto a la luz. PointLightBase expone una propiedad Range, que determina una distancia más allá de la cual la luz no iluminará los modelos. PointLight también expone propiedades de atenuación que determinan cómo disminuye la intensidad de la luz con la distancia. Puede especificar interpolaciones constantes, lineales o cuadráticas para la atenuación de la luz.

  • SpotLight: hereda de PointLight. Los focos de luz iluminan como las luces puntuales, y tienen posición y dirección. Proyectan la luz en una área cónica establecida por las propiedades InnerConeAngle y OuterConeAngle, especificadas en grados.

Las luces son objetos Model3D, por lo que puede transformar y animar las propiedades de la luz, incluidas su posición, posición, color, dirección y alcance.

<ModelVisual3D.Content>
    <AmbientLight Color="#333333" />
</ModelVisual3D.Content>
        Private myDirLight As New DirectionalLight()
DirectionalLight myDirLight = 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);

Transformar modelos

Al crear modelos, éstos tienen una ubicación determinada en la escena. Para mover esos modelos por la escena, girarlos o cambiar su tamaño, no es práctico para cambiar los vértices que definen los propios modelos. En lugar de ello, al igual que en 2-D, se aplican transformaciones a los modelos.

Cada objeto de modelo tiene una propiedad Transform con la que puede mover, reorientar o cambiar el tamaño del modelo. Al aplicar una transformación, en realidad lo que se hace es desplazar todos los puntos del modelo según un vector o valor especificado por la transformación. En otras palabras, se transforma el espacio de coordenadas en el que se ha definido el modelo ("espacio del modelo"), pero no se cambian los valores que constituyen la geometría del modelo en el sistema de coordenadas de la escena completa ("espacio universal").

Para obtener más información acerca de la transformación de modelos, consulte Información general sobre transformaciones de modelos 3D.

Animar modelos

La implementación de 3-D en WPF utiliza el mismo sistema de control de tiempo y animación que los gráficos 2-D. En otras palabras, para animar una escena 3D, se animan las propiedades de sus modelos. Es posible animar directamente las propiedades de los elementos primitivos, pero suele ser más fácil animar las transformaciones que cambian la posición o el aspecto de los modelos. Dado que las transformaciones se pueden aplicar a los objetos Model3DGroup así como a los modelos individuales, es posible de aplicar un conjunto de animaciones a un elemento secundario de Model3DGroup y otro conjunto de animaciones a un grupo de objetos secundarios. También puede lograr gran variedad de efectos visuales animando las propiedades de iluminación de la escena. Finalmente, si lo desea puede animar la propia proyección, animando la posición de la cámara o el campo de visión. Para obtener información general sobre el sistema de control de tiempo y animación de WPF, consulte los temas Información general sobre animaciones, Información general sobre objetos Storyboard y Información general sobre objetos Freezable.

Para animar un objeto en WPF, se crea una escala de tiempo, se define una animación (que, en realidad, es un cambio de algún valor de propiedad a lo largo del tiempo) y se especifica la propiedad a la que aplicar la animación. Dado que todos los objetos de una escena 3-D son elementos secundarios de Viewport3D, las propiedades de destino de cualquier animación que desea aplicar a la escena son propiedades de propiedades de Viewport3D.

Supongamos que desea hacer que un modelo parezca tambalearse en su lugar. Podría aplicar RotateTransform3D al modelo y animar el eje de giro de un vector a otro. En el ejemplo de código siguiente se muestra cómo aplicar Vector3DAnimation a la propiedad Axis de la propiedad Rotation3D de la transformación, suponiendo que RotateTransform3D es una de las diversas transformaciones aplicadas al modelo con TransformGroup.

            'Define a rotation
            Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
            Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
            myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
Vector3DAnimation myVectorAnimation = 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);

Agregar contenido 3D a la ventana

Para representar la escena, agregue modelos y luces a Model3DGroup, a continuación, establezca Model3DGroup en el Content de ModelVisual3D. Agregue ModelVisual3D a la colección Children de Viewport3D. Agregue cámaras a Viewport3D, estableciendo su propiedad Camera.

Finalmente, agregue Viewport3D a la ventana. Cuando se incluye Viewport3D como contenido de un elemento de diseño, como Canvas, debe especificar el tamaño de Viewport3D estableciendo las propiedades Height y Width (heredadas de FrameworkElement).

<UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Vea también

Referencia

Viewport3D

PerspectiveCamera

DirectionalLight

Material

Conceptos

Información general sobre transformaciones de modelos 3D

Maximizar el rendimiento de representación 3D en WPF

Información general sobre formas y dibujo básico en WPF

Pintar con imágenes, dibujos y elementos visuales

Otros recursos

Temas "Cómo..." de gráficos 3D