3D 圖形概觀
Windows Presentation Foundation (WPF) 中的 3D 功能可讓開發人員在標記和程序性程式碼中繪製和轉換 3D 圖形以及為 3D 圖形製作動畫。 開發人員可以結合 2D 和 3D 圖形來建立豐富的控制項、提供複雜的資料說明,或者加強應用程式介面的使用者體驗。 WPF 中的 3D 支援不適用於提供完整功能的遊戲開發平台。 本主題會提供 WPF 圖形系統中 3D 功能的概觀。
2D 容器中的 3D
WPF 中的 3D 圖形內容會封裝在一個可參與二維元素結構的 Viewport3D (部分機器翻譯) 元素中。 圖形系統會將 Viewport3D (部分機器翻譯) 視為二維的視覺元素,就像 WPF 中許多其他元素一樣。 Viewport3D (部分機器翻譯) 運作的方式就像視窗 (檢視區) 一樣,但是是在三維的場景。 更精確來說,這是 3D 場景投射到的表面。
在傳統的 2D 應用程式中,使用 Viewport3D (部分機器翻譯) 的方式就像您使用另一個容器元素 (例如格線或畫布) 一樣。 雖然您可以在相同的場景圖形中使用 Viewport3D (部分機器翻譯) 搭配其他 2D 繪圖物件,但您不能在 Viewport3D (部分機器翻譯) 內貫穿 2D 和 3D 物件。 本主題將著重於如何在 Viewport3D (部分機器翻譯) 內繪製 3D 圖形。
3D 座標空間
2D 圖形的 WPF 座標系統將原點置於轉譯區域 (通常是螢幕) 的左上角。 在 2D 系統中,X 軸的正值是往右,Y 軸的正值則是往下。 不過在 3D 座標系統中,原點是位於轉譯區域的中心,x 軸的正值是往右,但 y 軸的正值是往上,而 z 軸的正值是從原點朝向檢視器往外。
傳統的 2D 和 3D 座標系統表示法
這些軸所定義的空間是針對 WPF 中 3D 物件的靜態參考座標系。 當您在此空間中建置模型,並建立光線和觀景窗來檢視這些模型時,有助於區分此靜態參考座標系 (或稱為「世界空間」) 與您為每個模型套用轉換時建立的當地參考座標系。 也請記住,在世界空間中的物件取決於光線和觀景窗設定,可能看起來完全不同,或者完全無法看見,但觀景窗的位置不會改變世界空間中物件的位置。
觀景窗和投影
在 2D 環境中工作的開發人員習慣在二維的螢幕上安置繪圖基元。 當您建立 3D 場景時,請務必記住,您是真的要建立 3D 物件的 2D 表示法。 因為 3D 場景會隨旁觀者的視角而有所不同,所以您必須指定該視角。 Camera (部分機器翻譯) 類別可讓您指定 3D 場景的這個視角。
另一種了解如何在 2D 表面上表示 3D 場景的方式是將場景描述為在檢視表面上的投影。 ProjectionCamera (部分機器翻譯) 可讓您指定不同的投影及其屬性,以變更旁觀者如何看到 3D 模型。 PerspectiveCamera (部分機器翻譯) 會指定依透視法縮短場景的投影。 也就是說,PerspectiveCamera (部分機器翻譯) 會提供消失點的透視圖。 您可以指定觀景窗在場景座標空間中的位置、觀景窗的方向和視野,以及定義場景中「向上」方向的向量。 下圖說明 PerspectiveCamera (部分機器翻譯) 的投影。
ProjectionCamera (部分機器翻譯) 的 NearPlaneDistance (英文) 和 FarPlaneDistance (英文) 屬性會限制觀景窗的投影範圍。 由於觀景窗可能會位在場景中的任何地方,觀景窗有可能實際上就位在模型內部或非常靠近模型,因此更難正確區分物件。 NearPlaneDistance 可讓您指定與觀景窗之間的最小距離,超過此距離就不會繪製物件。 相反地,FarPlaneDistance (英文) 可讓您指定與觀景窗之間的距離,超過此距離就不會繪製物件,如此可確保場景中不會包含太遠而無法辨識的物件。
觀景窗位置
OrthographicCamera (部分機器翻譯) 會指定 3D 模型到 2D 視覺表面的正交投影。 與其他觀景窗相同,它會指定位置、檢視方向和「向上」方向。 不過與 PerspectiveCamera (部分機器翻譯) 不同的是,OrthographicCamera (部分機器翻譯) 描述的是不包含透視縮短的投影。 也就是說,OrthographicCamera (部分機器翻譯) 描述的是邊都平行,而不是邊會在觀景窗某個點相遇的檢視方塊。 下圖顯示使用 PerspectiveCamera (部分機器翻譯) 和 OrthographicCamera (部分機器翻譯) 來檢視時的同一個模型。
透視投影和正視投影
下列程式碼示範一些典型的觀景窗設定。
// 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
模型和網格基元
Model3D (部分機器翻譯) 是代表一般 3D 物件的抽象基底類別。 若要建置 3D 場景,需要一些可檢視的物件,以及衍生自 Model3D (部分機器翻譯)、構成場景圖形的物件。 WPF 目前支援使用 GeometryModel3D (部分機器翻譯) 來建立幾何模型。 此模型的 Geometry (部分機器翻譯) 屬性採用網格基元。
若要建立模型,請先建立基元 (也就是網格)。 3D 原始物件是形成單一 3D 實體的頂點集合。 大部分 3D 系統都提供以最簡單的封閉圖形 (由三個頂點定義的三角形) 塑造而成的基元。 因為三角形的三個點共面,所以您可以持續加入三角形,以塑造出更複雜的圖形 (稱為網格)。
WPF 3D 系統目前提供 MeshGeometry3D 類別,可讓您指定任何幾何;但目前不支援如球體和立方體這類預先定義的 3D 基元。 指定一份三角形頂點清單做為其 Positions (部分機器翻譯) 屬性來開始建立 MeshGeometry3D (部分機器翻譯)。 將每個頂點指定為 Point3D (英文)。 (在 XAML 中,將此屬性指定為以三個為一組的數字清單代表每個頂點的座標)。根據網格的幾何,網格可以由許多三角形組成,其中有些三角形會共用相同的角 (頂點)。 若要正確繪製網格,WPF 需要哪些三角形共用哪些頂點的相關資訊。 您可以使用 TriangleIndices (部分機器翻譯) 屬性指定一份三角形索引清單,來提供這項資訊。 此清單指定的順序,就是在 Positions (部分機器翻譯) 清單中指定的點將決定三角形的順序。
<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>
在上述範例中,Positions (部分機器翻譯) 清單會指定四個頂點來定義矩形網格。 TriangleIndices (部分機器翻譯) 屬性會指定一份有兩個群組的清單,每個群組由三個索引組成。 清單中的每個數字都會參考 Positions (部分機器翻譯) 清單中的位移。 例如,Positions (部分機器翻譯) 清單所指定的前三個頂點是 (-1,-1,0)、(1,-1,0) 和 (-1,1,0)。 TriangleIndices (部分機器翻譯) 清單所指定的前三個索引是 0、1 和 2,這會對應到 Positions (部分機器翻譯) 清單中的第一個點、第二個點和第三個點。 因此,組成矩形模型的第一個三角形將會從 (-1,-1,0) 到 (1,-1,0) 到 (-1,1,0) 組成,第二個三角形也同樣如此決定。
您可以指定 Normals (部分機器翻譯) 和 TextureCoordinates (部分機器翻譯) 屬性的值繼續定義模型。 若要轉譯模型的表面,圖形系統需要表面在任意指定的三角形處面對哪個方向的資訊。 系統會使用此資訊來進行模型的光線計算︰直接面向光源的表面看起來就會比偏離光線一些角度的表面還亮。 雖然 WPF 可以使用位置座標決定預設的法向向量,但是您也可以指定不同的法向向量以模擬曲面的外觀。
TextureCoordinates (部分機器翻譯) 屬性指定一系列的 Point (英文),告訴圖形系統如何將決定如何繪製紋理的座標對應到網格的頂點。 TextureCoordinates (部分機器翻譯) 已指定為介於 0 到 1 (含) 之間的值。 如同 Normals (部分機器翻譯) 屬性,圖形系統可以計算預設的紋理座標,但是您可以選擇設定不同的紋理座標,來控制例如包含部分重複模式之紋理的對應。 您可以在後續的主題或 Managed Direct3D SDK 中找到有關紋理座標的詳細資訊。
下列範例示範如何以程序性程式碼建立立方體模型的一個面。 您可以將整個立方體繪製為單一一個 GeometryModel3D
;此範例會將立方體的面繪製為不同的模型以便稍後對每個面套用不同的紋理。
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))
對模型套用材質
若要讓網格看起來像三維物件,就必須套用紋理以涵蓋由其頂點和三角形所定義的表面,讓觀景窗可以點亮並投影表面。 在 2D 中,您要使用 Brush (部分機器翻譯) 類別對螢幕的區域套用色彩、圖樣、漸層或其他視覺內容。 不過,3D 物件的外觀是光源模型的函式,而不只是對物件套用的色彩或圖樣。 真實的物體會根據物體表面的質地以不同方式反射光線︰光滑而閃亮的表面看起來會與粗糙或黯淡的表面不同,而一些物體看起來會吸收光線,一些物體則會發亮。 可對 2D 物件套用的所有筆刷都可對 3D 物件套用,但是您無法直接套用。
為了定義模型表面的特性,WPF 會使用 Material (部分機器翻譯) 抽象類別。 Material 的具體子類別會決定模型表面的一些外觀特性,每個特性也提供您可以傳遞 SolidColorBrush、TileBrush 或 VisualBrush 的 Brush 屬性。
DiffuseMaterial (部分機器翻譯) 指定要對模型套用筆刷,就像以漫射方式照亮模型。 使用 DiffuseMaterial 非常類似直接對 2D 模型使用筆刷;模型表面不會反射光線但看起來閃亮。
SpecularMaterial (部分機器翻譯) 指定要對模型套用筆刷,讓模型表面看起來堅硬或閃亮,能夠反射強光。 您可以指定 SpecularPower (部分機器翻譯) 屬性的值來設定紋理將達到此反射質地或「閃亮」的程度。
EmissiveMaterial (部分機器翻譯) 可讓您指定將套用紋理,讓模型看起來像發出相當於筆刷色彩的光線。 這不會讓模型變成光源。不過,這會影響陰影處理的方式,與透過 DiffuseMaterial 或 SpecularMaterial 加上紋理的方式不同。
為了達到最佳效能,會從場景剔除 GeometryModel3D (部分機器翻譯) 的背面 (從觀景窗看出去,位於模型的另一側而看不見的那些面)。 若要指定對模型背面 (例如平面) 套用的 Material (部分機器翻譯),請設定模型的 BackMaterial (英文) 屬性。
若要達到某些表面質地,例如發光或反射效果,您可以對模型連續套用數種不同的筆刷。 您可以使用 MaterialGroup (部分機器翻譯) 類別套用及重複使用多個 Material。 在多個轉譯階段中,會從頭到尾套用 MaterialGroup 的子系。
下列程式碼範例示範如何對 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))
場景照明
3D 圖形中的光線運作方式和真實世界的光線相同︰讓表面看得見。 而且,光線還會決定投影時要包含場景的哪個部分。 WPF 中的光線物件會建立各種光線和陰影效果,而且會仿照真實世界各種光線的行為。 請在場景中至少包含一種光線,否則會看不到模型。
下列光線衍生自基底類別 Light (部分機器翻譯):
AmbientLight (部分機器翻譯)︰提供均勻照亮所有物件的環境光線,不論物件的位置或方向為何。
DirectionalLight (部分機器翻譯):像是以遠距離的光源照明。 定向光線有 Direction (英文) 指定為 Vector3D,但沒有指定位置。
PointLight (部分機器翻譯):像是以近距離的光源照明。 PointLights 有一個位置,並從該位置投射光線。 場景中的物件會根據其相對於光線的位置和距離來照明。 PointLightBase (部分機器翻譯) 公開 Range (英文) 屬性,決定光線不會照到模型的距離。 PointLight 也公開衰減屬性,決定光線強度如何隨距離而降低。 您可以為光線衰減指定常數、線性插補或二次插補。
SpotLight (部分機器翻譯)︰繼承自 PointLight (部分機器翻譯)。 Spotlight 照明的方式類似 PointLight,而且有位置和方向兩者。 它們會將光線投射在 InnerConeAngle (部分機器翻譯) 和 OuterConeAngle (部分機器翻譯) 屬性 (以度為單位指定) 設定的圓錐形區域中。
光線是 Model3D (部分機器翻譯) 物件,因此您可以轉換和以動畫顯示光線的屬性,包括位置、色彩、方向和範圍。
<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)
轉換模型
當您建立模型時,模型在場景中有特定的位置。 若要在場景中四處移動模型、旋轉模型,或變更模型的大小,變更定義模型的頂點本身並不實用。 而是要像在 2D 一樣,對模型套用轉換。
每個模型物件都有 Transform (英文) 屬性,可用來移動模型、調整模型方向,或調整模型大小。 當您套用轉換時,可以透過轉換所指定的任何向量或值,有效率地位移模型的所有點。 換句話說,您已經轉換定義模型所在的座標空間 (「模型空間」),但尚未變更在整個場景的座標系統 (「世界空間」) 中組成模型幾何的值。
如需轉換模型的詳細資訊,請參閱 3D 轉換概觀。
以動畫顯示模型
WPF 3D 實作會參與和 2D 圖形相同的計時和動畫系統。 換句話說,若要以動畫顯示 3D 場景,就要以動畫顯示其模型的屬性。 您可以直接以動畫顯示基元的屬性,但是以動畫顯示變更模型位置或外觀的轉換通常更容易。 因為可以對 Model3DGroup (部分機器翻譯) 物件以及個別模型套用轉換,所以就可以對 Model3DGroup 的子系套用一組動畫,然後對一組子系物件套用另一組動畫。 您也可以以動畫顯示場景光線的屬性,達到各種視覺效果。 最後,您還可以選擇以動畫顯示觀景窗的位置或視野,以動畫顯示投影本身。 如需 WPF 計時和動畫系統的背景資訊,請參閱動畫概觀、分鏡腳本概觀,以及 Freezable 物件概觀等主題。
若要以動畫顯示 WPF 中的物件,您要建立時間軸、定義動畫 (這實際上是某些屬性值隨時間的變化),並指定要套用動畫的屬性。 因為在 3D 場景中所有物件都是 Viewport3D (部分機器翻譯) 的子系,所以您想要套用至場景之任何動畫的目標屬性都是 Viewport3D 的屬性。
假設您想要讓模型就地搖晃。 您可以選擇對模型套用 RotateTransform3D (部分機器翻譯),然後讓其旋轉軸從一個向量到另一個向量以動畫顯示。 下列程式碼範例示範如何對轉換之 Rotation3D 的 Axis 屬性套用 Vector3DAnimation,假設 RotateTransform3D 是要使用 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)
在視窗中新增 3D 內容
若要轉譯場景,請在 Model3DGroup (部分機器翻譯) 中新增模型和光線,然後將 Model3DGroup (部分機器翻譯) 設定為 ModelVisual3D (英文) 的 Content (英文)。 將 ModelVisual3D (英文) 新增至 Viewport3D (部分機器翻譯) 的 Children (英文) 集合。 在 Viewport3D (部分機器翻譯) 中新增觀景窗,方法是設定 Viewport3D 的 Camera (英文) 屬性。
最後,在視窗中新增 Viewport3D (部分機器翻譯)。 當 Viewport3D (部分機器翻譯) 是版面配置元素 (例如畫布) 的內容時,請設定 Viewport3D 的 Height (部分機器翻譯) 和 Width (部分機器翻譯) 屬性 (繼承自 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>