Visão geral dos gráficos 3D
a funcionalidade 3D no WPF (Windows Presentation Foundation) permite que os desenvolvedores desenhem, transformem e animem elementos gráficos 3D na marcação e no código processual. Os desenvolvedores podem combinar elementos gráficos 2D e 3D para criar controles avançados, fornecer ilustrações complexas de dados ou aprimorar a experiência do usuário da interface de um aplicativo. O suporte 3D no WPF não foi projetado para fornecer uma plataforma de desenvolvimento de jogos completa. Este tópico fornece uma visão geral da funcionalidade 3D no sistema gráfico do WPF.
3D em um contêiner 2D
O conteúdo de elementos gráficos 3D no WPF é encapsulado em um elemento, Viewport3D, que pode participar da estrutura de elemento bidimensional. O sistema gráfico trata Viewport3D como um elemento visual bidimensional como muitos outros no WPF. Viewport3D funciona como uma janela—um viewport—para uma cena tridimensional. Mais precisamente, é uma superfície na qual uma cena 3D é projetada.
Em um aplicativo 2D convencional, use Viewport3D como faria com outro elemento de contêiner, como Grid ou Canvas. Embora você possa usar Viewport3D com outros objetos de desenho 2D no mesmo grafo de cena, não é possível interpenetrar objetos 2D e 3D em um Viewport3D. Este tópico se concentrará em como desenhar elementos gráficos 3D dentro do Viewport3D.
Espaço de coordenada 3D
O sistema de coordenadas WPF para gráficos 2D localiza a origem no canto superior esquerdo da área de renderização (normalmente a tela). No sistema 2D, os valores positivos do eixo x prossseguem para a direita e os valores positivos do eixo y prossseguem para baixo. No sistema de coordenadas 3D, no entanto, a origem está localizada no centro da área de renderização, com valores positivos do eixo x continuando para a direita, mas valores positivos do eixo y, continuando para cima e valores positivos do eixo z continuando para fora da origem, em direção ao visualizador.
Sistemas de coordenadas CoordSystem-1
Representações convencionais do sistema de coordenadas 2D e 3D
O espaço definido por esses eixos é o quadro estacionário de referência para objetos 3D no WPF. À medida que você cria modelos nesse espaço e cria luzes e câmeras para visualizá-los, é útil distinguir esse quadro de referência estacionário ou "espaço no mundo", do quadro de referência local que você cria para cada modelo ao aplicar transformações a ele. Lembre-se também de que os objetos no espaço mundial podem parecer totalmente diferentes ou não estar visíveis, dependendo das configurações de luz e câmera, mas a posição da câmera não altera o local dos objetos no espaço mundial.
Câmeras e projeções
Os desenvolvedores que trabalham em 2D estão acostumados a posicionar primitivos de desenho em uma tela bidimensional. Ao criar uma cena 3D, é importante lembrar que você está realmente criando uma representação 2D de objetos 3D. Como uma cena 3D parece diferente dependendo do ponto de vista do espectador, você deve especificar esse ponto de vista. A classe Camera permite que você especifique esse ponto de exibição para uma cena 3D.
Outra maneira de entender como uma cena 3D é representada em uma superfície 2D é descrevendo a cena como uma projeção na superfície de exibição. O ProjectionCamera permite que você especifique projeções diferentes e suas propriedades para alterar a forma como o espectador vê modelos 3D. Um PerspectiveCamera especifica uma projeção que encurta a cena. Em outras palavras, o PerspectiveCamera fornece a perspectiva do ponto de fuga. Você pode especificar a posição da câmera no espaço de coordenadas da cena, a direção e o campo de visão da câmera e um vetor que define a direção “para cima” na cena. O diagrama a seguir ilustra a projeção do PerspectiveCamera.
As propriedades NearPlaneDistance e FarPlaneDistance de ProjectionCamera limitam o intervalo da projeção da câmera. Como as câmeras podem estar localizadas em qualquer lugar da cena, é possível que a câmera seja realmente posicionada dentro de um modelo ou muito perto de um modelo, tornando difícil distinguir objetos corretamente. NearPlaneDistance permite que você especifique uma distância mínima da câmera além da qual os objetos não serão desenhados. Por outro lado, FarPlaneDistance permite que você especifique uma distância da câmera além da qual os objetos não serão desenhados, o que garante que objetos muito distantes para serem reconhecíveis não sejam incluídos na cena.
instalação da câmera
Posição da câmera
OrthographicCamera especifica uma projeção ortogonal de um modelo 3D para uma superfície visual 2D. Como outras câmeras, ele especifica uma posição, direção de exibição e direção "para cima". Ao contrário de PerspectiveCamera, OrthographicCamera, porém, descreve uma projeção que não inclui encurtamento perspectivo. Em outras palavras, OrthographicCamera descreve uma caixa de visualização cujos lados são paralelos, em vez de uma cujos lados se encontram em um ponto na câmera. A imagem a seguir mostra o mesmo modelo exibido usando PerspectiveCamera e OrthographicCamera.
projeção ortográfica e de perspectiva
Perspectiva e projeções ortográficas
O código a seguir mostra algumas configurações típicas da câmera.
// 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
Primitivos de malha e de modelo
Model3D é a classe base abstrata que representa um objeto 3D genérico. Para criar uma cena 3D, você precisa de alguns objetos para exibir e os objetos que compõem o grafo de cena derivam de Model3D. Atualmente, o WPF dá suporte à modelagem de geometrias com GeometryModel3D. A propriedade Geometry deste modelo aceita um primitivo de malha.
Para criar um modelo, comece criando um primitivo ou uma malha. Um primitivo 3D é uma coleção de vértices que formam uma única entidade 3D. A maioria dos sistemas 3D fornece primitivos modelados na figura fechada mais simples: um triângulo definido por três vértices. Como os três pontos de um triângulo são coplanares, você pode continuar adicionando triângulos para modelar formas mais complexas, chamadas malhas.
O sistema 3D do WPF atualmente fornece a classe MeshGeometry3D, que permite especificar qualquer geometria; atualmente, ele não dá suporte a primitivos 3D predefinidos, como esferas e formas cúbicas. Comece a criar uma MeshGeometry3D especificando uma lista de vértices de triângulo como respectiva propriedade Positions. Cada vértice é especificado como um Point3D. (Em XAML, especifique essa propriedade como uma lista de números agrupados em três que representam as coordenadas de cada vértice.) Dependendo de sua geometria, sua malha pode ser composta por muitos triângulos, alguns dos quais compartilham os mesmos cantos (vértices). Para desenhar a malha corretamente, o WPF precisa de informações sobre quais vértices são compartilhados por quais triângulos. Você fornece essas informações especificando uma lista de índices de triângulo com a propriedade TriangleIndices. Esta lista especifica a ordem na qual os pontos especificados na lista de Positions determinarão um 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>
No exemplo anterior, a lista Positions especifica quatro vértices para definir uma malha de retângulo. A propriedade TriangleIndices especifica uma lista de dois grupos de três índices. Cada número na lista refere a um deslocamento na lista Positions. Por exemplo, os três primeiros vértices especificados pela lista de Positions são (-1,-1,0), (1,-1,0)e (-1,1,0). Os três primeiros índices especificados pela lista TriangleIndices são 0, 1 e 2, que correspondem ao primeiro, segundo e terceiro pontos na lista de Positions. Como resultado, o primeiro triângulo que compõe o modelo de retângulo será composto de (-1,-1,0) a (1,-1,0) a (-1,1,0)e o segundo triângulo será determinado da mesma forma.
Você pode continuar definindo o modelo especificando valores para as propriedades Normals e TextureCoordinates. Para renderizar a superfície do modelo, o sistema gráfico precisa de informações sobre qual direção a superfície está voltada para qualquer triângulo específico. Ele usa essas informações para fazer cálculos de iluminação para o modelo: superfícies que estão voltadas diretamente para uma fonte de luz parecem mais brilhantes do que aquelas anguladas longe da luz. Embora o WPF possa determinar vetores normais padrão usando as coordenadas de posição, você também pode especificar diferentes vetores normais para aproximar a aparência de superfícies curvas.
A propriedade TextureCoordinates especifica uma coleção de Points que informam ao sistema gráfico como mapear as coordenadas que determinam como uma textura é desenhada para os vértices da malha. TextureCoordinates são especificados como um valor entre zero e 1, inclusive. Assim como acontece com a propriedade Normals, o sistema gráfico pode calcular coordenadas de textura padrão, mas você pode optar por definir coordenadas de textura diferentes para controlar o mapeamento de uma textura que inclui parte de um padrão de repetição, por exemplo. Mais informações sobre coordenadas de textura podem ser encontradas em tópicos subsequentes ou no SDK do Direct3D Gerenciado.
O exemplo a seguir mostra como criar uma face do modelo de cubo no código processual. Você pode desenhar o cubo inteiro como um único GeometryModel3D
; este exemplo desenha o rosto do cubo como um modelo distinto para aplicar texturas separadas a cada rosto posteriormente.
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))
Aplicando materiais ao modelo
Para que uma malha pareça um objeto tridimensional, ela deve ter uma textura aplicada para cobrir a superfície definida por seus vértices e triângulos para que possa ser iluminada e projetada pela câmera. Em 2D, você usa a classe Brush para aplicar cores, padrões, gradientes ou outro conteúdo visual a áreas da tela. A aparência de objetos 3D, no entanto, é uma função do modelo de iluminação, não apenas da cor ou padrão aplicado a eles. Objetos do mundo real refletem a luz de forma diferente dependendo da qualidade de suas superfícies: superfícies brilhantes e lustrosas não parecem iguais a superfícies rugosas ou foscas, e alguns objetos parecem absorver luz enquanto outros parecem brilhar. Você pode aplicar todos os mesmos pincéis a objetos 3D que podem ser aplicados a objetos 2D, mas não é possível aplicá-los diretamente.
Para definir as características da superfície de um modelo, o WPF usa a classe abstrata Material. As subclasses concretas de Material determinam algumas das características de aparência da superfície do modelo, e cada uma delas também fornece uma propriedade Brush para a qual você pode passar um SolidColorBrush, TileBrush ou VisualBrush.
DiffuseMaterial especifica que o pincel será aplicado ao modelo como se esse modelo tivesse sido iluminado difusamente. Usar DiffuseMaterial é mais parecido com o uso de pincéis diretamente em modelos 2D; superfícies de modelo não refletem a luz como se fossem brilhantes.
SpecularMaterial especifica que o pincel será aplicado ao modelo como se a superfície do modelo fosse dura ou brilhante, capaz de refletir realces. Você pode definir o grau em que a textura sugerirá essa qualidade reflexiva ou "brilho", especificando um valor para a propriedade SpecularPower.
EmissiveMaterial permite especificar que a textura será aplicada como se o modelo estivesse emitindo luz igual à cor do pincel. Isso não torna o modelo uma luz; no entanto, ele terá um papel diferente no sombreamento do que teria se fosse texturizado com Material Difuso ou Material Especular.
Para obter um melhor desempenho, as faces traseiras de um GeometryModel3D (as faces que estão fora da exibição por estarem do lado oposto do modelo da câmera) são cortadas da cena. Para especificar um Material a ser aplicado à face traseira de um modelo como um plano, defina a propriedade BackMaterial do modelo.
Para obter algumas qualidades de superfície, como efeitos brilhantes ou reflexivos, talvez você queira aplicar vários pincéis diferentes a um modelo em sucessão. Você pode aplicar e reutilizar vários materiais usando a classe MaterialGroup. Os filhos do MaterialGroup são aplicados do primeiro ao último em várias aplicações de renderização.
Os exemplos de código a seguir mostram como aplicar uma cor sólida e um desenho como pincéis a modelos 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))
Iluminando a cena
As luzes em gráficos 3D fazem o que as luzes fazem no mundo real: elas tornam as superfícies visíveis. Mais ao ponto, as luzes determinam qual parte de uma cena será incluída na projeção. Objetos claros no WPF criam uma variedade de efeitos de luz e sombra e são modelados após o comportamento de várias luzes do mundo real. Inclua pelo menos uma luz em sua cena ou nenhum modelo ficará visível.
As seguintes luzes derivam da classe base Light:
AmbientLight: fornece iluminação ambiente que ilumina todos os objetos uniformemente, independentemente de sua localização ou orientação.
DirectionalLight: ilumina como uma fonte de luz distante. As luzes direcionais têm um Direction especificado como um Vector3D, mas nenhuma localização especificada.
PointLight: ilumina como uma fonte de luz próxima. As PointLights têm uma posição e lançam uma luz dessa posição. Os objetos na cena são iluminados dependendo de sua posição e distância em relação à luz. PointLightBase expõe uma propriedade Range, que determina uma distância além da qual os modelos não serão iluminados pela luz. PointLight também expõe propriedades de atenuação, que determinam como a intensidade da luz diminui ao longo da distância. Você pode especificar interpolações constantes, lineares ou quadráticas para atenuação da luz.
SpotLight: Herda de PointLight. Os destaques iluminam como PointLight e têm posição e direção. Eles projetam luz em uma área em forma de cone definida por propriedades InnerConeAngle e OuterConeAngle, especificadas em graus.
As luzes são objetos Model3D, assim você pode transformar e animar propriedades de luz, incluindo posição, cor, direção e alcance.
<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)
Transformando modelos
Quando você cria modelos, eles têm uma posição específica na cena. Para mover esses modelos na cena, para girá-los ou para alterar seu tamanho, não é prático alterar os vértices que definem os próprios modelos. Em vez disso, assim como no 2D, você aplica transformações a modelos.
Cada objeto de modelo tem uma propriedade Transform com a qual você pode mover, reorientar ou redimensionar o modelo. Ao aplicar uma transformação, você efetivamente compensa todos os pontos do modelo por qualquer vetor ou valor especificado pela transformação. Em outras palavras, você transformou o espaço de coordenadas no qual o modelo é definido ("espaço de modelo"), mas não alterou os valores que compõem a geometria do modelo no sistema de coordenadas de toda a cena ("espaço mundial").
Para obter mais informações sobre como transformar modelos, consulte Visão geral de transformações 3D.
Animando modelos
A implementação do WPF 3D participa do mesmo sistema de tempo e animação que os gráficos 2D. Em outras palavras, para animar uma cena 3D, anime as propriedades dos modelos dela. É possível animar as propriedades dos primitivos diretamente, mas normalmente é mais fácil animar transformações que alteram a posição ou a aparência dos modelos. Como as transformações podem ser aplicadas a objetos Model3DGroup, bem como a modelos individuais, é possível aplicar um conjunto de animações a um filho de um Model3DGroup e outro conjunto de animações a um grupo de objetos filho. Você também pode obter uma variedade de efeitos visuais animando as propriedades de iluminação da cena. Por fim, você pode optar por animar a projeção em si animando a posição da câmera ou o campo de exibição. Para obter informações de base sobre o sistema de tempo e animação do WPF, consulte os tópicos Visão Geral da Animação, Visão Geral de Storyboardse Visão Geral de Objetos Congeláveis.
Para animar um objeto no WPF, crie uma linha do tempo, defina uma animação (que é realmente uma alteração em algum valor de propriedade ao longo do tempo) e especifique a propriedade à qual aplicar a animação. Como todos os objetos em uma cena 3D são filhos de Viewport3D, as propriedades que qualquer animação busca modificar na cena são propriedades do Viewport3D.
Suponha que você queira fazer com que um modelo pareça oscilar no lugar. Você pode optar por aplicar uma RotateTransform3D ao modelo e animar o eixo de sua rotação de um vetor para outro. O exemplo de código a seguir demonstra a aplicação de uma Vector3DAnimation à propriedade do Eixo da Rotation3D da transformação, supondo que a RotateTransform3D seja uma das várias transformações aplicadas ao modelo com um 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)
Adicionar conteúdo 3D à janela
Para renderizar a cena, adicione modelos e luzes a um Model3DGroupe, em seguida, defina o Model3DGroup como o Content de um ModelVisual3D. Adicione o ModelVisual3D à coleção Children do Viewport3D. Adicione câmeras ao Viewport3D configurando a propriedade Camera.
Por fim, adicione o Viewport3D à janela. Quando o Viewport3D é incluído como o conteúdo de um elemento de layout como Canvas, especifique o tamanho do Viewport3D definindo suas propriedades Height e Width (herdadas de 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>
Consulte também
.NET Desktop feedback