WPF 3D坐標


坐標系 Coodinate System

WPF中二維圖形的坐標系將原點定位在呈現區域(通常是屏幕)的左上角。 在二維系統中,x 軸上的正值朝右,y 軸上的正值朝下。而在三維坐標系中,原點位於呈現區域的中心,x 軸上的正值朝右,但是 y 軸上的正值朝上,z 軸上的正值從原點向外朝向觀察者。傳統的二維和三維坐標系表示形式如下圖
coordinate system

由這些軸定義的空間是三維對象在 WPF 中的固定參考框架。
當您在該空間中生成模型並創建光源和照相機以查看這些模型時,一定要在向每個模型應用變換時,將固定參考框架或“全局空間”與您為該模型創建的局部參考框架區分開。

另請記住,根據光源和照相機設置,全局空間中的對象可能會看上去完全不同或者根本不可見,但是照相機的位置不會改變對象在全局空間中的位置。

3D的世界都是三角形的王國

3D Model

在3D的世界里所有的東西都是用一些列的“三角形”來描述的。那你一定會問為什么是“三角形”?
原因是三角形是用來描述一個平面的最細微的幾何體,渲染引擎能夠依據每個三角形的材質以及場景中的燈光角度來計算它的顏色。
其實就是三點確定一個平面,在一個平面上做計算最簡單,考慮的因素最少。如果用三維空間中大於三個點來做渲染基本單位,那么如果這些點不在同一個平面上的話,渲染計算是相當復雜的。

3D 對象的表面叫做網格(Mesh),一個網格是由許多3D 點來定義的,這些點叫做頂點(vertices)。這些頂點通過纏繞模式(winding pattern)連接在一起組成一個一個的三角形(facet)(如下圖箭頭所示)。
在這里插入圖片描述
三角形(facet/triangle)又分為“前”和“后”兩面,能看到的部分為前面,看不到的部分為后面。

那怎么判定是前面還是后面?

如果三角形的三個點順時針方向組成的面那么這個面就是前面。如下圖

在這里插入圖片描述
按照0,1,2的順序三個點組成了的這個面是上面我們可以看到

實際上是因為正面和反面的法向量(垂直於平面)與是向量的夾角,夾角小於90 說明是正面可以看見,反之是反面。

目前主流(Direct3D and/or OpenGL)都會把三角形分為兩個面(前面和后面)。

為幫助大家記憶(facet)“前面”的三維坐標,大拇指是Z+的方向正對着我們(及前面圖示中Up方向),食指是y+方向,而中指是Y+方向。(+表示正數的方向)
在這里插入圖片描述

WPF 3D的關鍵元素(Elements)

在這里插入圖片描述

要畫畫總的有個畫布,WPF中呈現3D也需要一個類似功能的東西。Viewport3D(投影3D場景的平面)是WPF中的3D畫布,類於2D中的Canvas。其實WPF中也有一個名字看起來類似的東東Viewbox ,不過和3D沒啥關系,它處理的都是2D的。

<Viewport3D> Children… </Viewport3D> 
  • 1
  • 2
  • 3

該圖形系統將 Viewport3D 視為一個像 WPF 中的許多其他元素一樣的二維可視化元素。
Viewport3D充當三維場景中的窗口(即視區)。 更准確地說,它是三維場景所投影到的圖面。

相機(Camera)

處理二維對象的開發人員習慣於將繪圖基元置於二維屏幕上。 當您創建三維場景時,一定要記住您實際上是要創建三維對象的二維表示形式。 由於三維場景的外觀會因觀察者的觀察位置不同而異,因此您必須指定觀察位置。而觀察位置就是由相機(Camera 類)來為三維場景指定的。

另一種理解三維場景在二維圖上的描述方法就是,將3D場景投影到一個2D平面的表面。如下圖:
在這里插入圖片描述
從坐標系的角度來看下我們的ProjectionCamera(透視相機)和3D模型的位置,以及2D 投影屏幕的位置關系:

在這里插入圖片描述
更詳細的圖解如下:
在這里插入圖片描述

ProjectionCamera 的 NearPlaneDistance 和 FarPlaneDistance
屬性限制照相機的投影范圍。由於照相機可以位於場景中的任何位置,因此照相機實際上可能會位於模型內部或者緊靠模型,這使正確區分對象變得很困難。
通過 NearPlaneDistance,可以指定一個距離照相機的最小距離,超過該距離后即不繪制對象。 相反,使用
FarPlaneDistance,可以指定一個距離照相機的距離(即,在超過該距離后將不繪制對象),從而確保因距離太遠而無法識別的對象將不包括在場景中。

對比WPF中兩種相機

PerspectiveCamera 可以指定不同的投影及其屬性以更改觀察者查看三維模型的方式。
OrthographicCamera 指定三維模型到二維可視化圖面上的正投影與其他照相機一樣,它指定位置、觀察方向和“向上”方向。 但是,與 PerspectiveCamera 不同的是,OrthographicCamera 描述了不包括透視收縮的投影。或者說OrthographicCamera 描述了一個側面平行的取景框,而不是側面匯集在場景中一點的取景框。
下圖演示使用PerspectiveCamera 和 OrthographicCamera 查看同一模型時的不同效果。

在這里插入圖片描述

燈光

和現實生活中一樣,如果沒有光我們將什么也看不到。因此我們需要在我們的場景中至少放置一盞燈來照亮我們場景中的模型。

WPF中支持不同類型的光源,如下:

  • AmbientLight(環境光) 它所提供的環境光會照亮所有的對象,而不考慮對象的位置或方向。
  • DirectionalLight(平行光) 像遠處的光源那樣照亮(如太陽光)。將方向光的 Direction 指定為 Vector3D,但是沒有為方向光指定位置。
  • PointLight(點光源) 像近處的光源那樣照亮。 PointLight 具有一個位置並從該位置投射光。 場景中的對象是根據對象相對於光源的位置和距離而被照亮的。 PointLightBase 公開 Range 屬性,該屬性確定一個距離,超過該距離后模型將無法由光源照亮。 PointLight 還公開了多個衰減屬性,這些屬性確定光源的亮度如何隨距離的增加而減小。 您可以為光源的衰減指定恆定、線性或二次內插算法。
  • SpotLight(聚光燈) 從 PointLight 繼承。 Spotlight 的照亮方式與 PointLight 類似,但是它既具有位置又具有方向。 它們在 InnerConeAngle 和 OuterConeAngle 屬性所設置的錐形區域(以度為單位指定)中投射光。

下圖展示了各種光源的情況:
在這里插入圖片描述

光源是 Model3D 對象,因此您可以轉換光源對象並對光源屬性(包括位置、顏色、方向和范圍)進行動畫處理。

組合燈光的效果

  • Ambient color : Red
  • Difusse color : Red

在這里插入圖片描述

3D模型

說了半天啦,怎么主角還沒出現了 ??

對,所有的一切都服務於我們的3D Model。
在這里插入圖片描述
Model3D 是三維對象的抽象基類。若要生成三維場景,需要一些要查看的對象,而且構成場景圖的對象必須派生自 Model3D。 目前,WPF 支持用 GeometryModel3D 對幾何形狀進行建模。 此模型的 Geometry 屬性采用網格基元。

要生成模型,首先生成一個基元或網格。 三維基元是一系列構成單個三維實體的頂點。 大多數三維系統都提供在最簡單的閉合圖(由三個頂點定義的三角形)上建模的基元。 由於三角形的三個點在一個平面上,因此您可以繼續添加三角形,以便對網格這樣較為復雜的形狀建模。

WPF 三維系統目前提供 MeshGeometry3D 類,使用該類可以指定任何幾何形狀;它目前不支持預定義的三維基元(如球體和立方體)。 首先通過將三角形頂點的列表指定為它的Positions 屬性來創建 MeshGeometry3D。 每個頂點都指定為 Point3D。 (在可擴展應用程序標記語言 (XAML) 中,將該屬性指定為三個一組的數字列表,每組中的三個數字表示每個頂點的坐標)。根據網格的幾何形狀,網格可能會由多個三角形組成,其中的一些三角形共用相同的角(頂點)。 若要正確地繪制網格,WPF 需要有關哪些頂點由哪些三角形共用的信息。 可以通過指定具有 TriangleIndices 屬性的三角形索引列表來提供此信息。 此列表指定在 Positions 列表中指定的點將按哪種順序確定三角形。

材質(Material)

我們生活在多彩的世界中,也不能讓我們的3D模型如此單調,這時我們就用到了材質。
在這里插入圖片描述
在二維中,可以使用 Brush 類來向屏幕中的區域應用顏色、圖案、漸變或其他可視化內容。 但是,三維對象的外觀是照明模型的功能,而不只是應用於它們的顏色或圖案。 實際對象的圖面質量不同,它們反射光的方式也會有所不同:光亮的圖面與粗糙或不光滑的圖面看上去不同,某些對象似乎可以吸收光,而某些對象似乎能夠發光。 您可以向三維對象應用與應用於二維對象的完全相同的畫筆,但是您不能直接應用它們。

Material 的具體子類用來確定模型圖面的某些外觀特征,每個子類還提供一個可以向其傳遞 SolidColorBrush、TileBrush 或 VisualBrush 的 Brush 屬性。

  • DiffuseMaterial 使用 DiffuseMaterial 與直接針對二維模型使用畫筆非常相似;模型表面不反射光,就好像是自發光一樣。使用 DiffuseMaterial 與直接針對二維模型使用畫筆非常相似;模型表面不反射光,就好像是自發光一樣
  • SpecularMaterial 可以通過為 SpecularPower 屬性指定一個值來設置系統將為紋理的反射特質(或“發光”)建議的度數。
  • EmissiveMaterial 可以指定將應用紋理,就好像模型所發出的光與畫筆的顏色相同。這不會使模型成為光源;但是,它參與陰影設置的方式將不同於用 DiffuseMaterial 或 SpecularMaterial 設置紋理時的情況。
    在這里插入圖片描述

為進一步提高性能,可以從場景中精選 GeometryModel3D 的背面(由於它們相對於照相機位於模型的背面,因此您將看不到這些面)。若要指定要應用於模型(如飛機)背面的Material,請設置模型的 BackMaterial 屬性。

為了實現某些圖面質量(如發光或發射效果),您可能希望向模型連續應用幾個不同的畫筆。 可以使用 MaterialGroup 類來應用和重用多個 Material。 MaterialGroup 的子級在多個呈現過程中按照從頭到尾的順序來應用。

WPF 中的3D變換

在這里插入圖片描述

當您創建模型時,它們在場景中具有固定的位置。為了在場景中移動、旋轉這些模型或者更改這些模型的大小而更改用來定義模型本身的頂點是不切實際的。 相反,您可以像在二維模型一樣應用轉換。

每個模型對象都有一個可用來對模型進行移動、重定向或調整大小的 Transform 屬性。 當您應用轉換時,實際上是按照由Transform 屬性指定的向量或值來偏移模型的所有點。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM