1. 程式人生 > >#WPF的3D開發技術基礎梳理

#WPF的3D開發技術基礎梳理

.aspx ews lan 角度 rail 右下角 ont 英雄 style

原文:#WPF的3D開發技術基礎梳理

自學WPF已經有半年有余了,一遍用,一邊學。但是一直沒有去觸摸WPF的3D開發相關技術,因為總覺得在內心是一座大山,覺得自己沒有能力去逾越。最近因為一個項目的相關原因,需要用的3D技術,雖然內心沒有底只能硬著頭皮上了。最後效果還不錯。
開發完之後,對WPF的開發小有所感,於是打算寫下來,把相關知識梳理下。給正在學習WPF技術夥伴們一點幫助。
能力平平,知識有限,如有錯誤,還望雅正。

   作為微軟推廣的一門軟件開發技術,肯定會遵循一個基本準則:怎麽方便怎麽來,怎麽舒服怎麽來。說的有點帶色彩,但理沒錯。我們在學習這些知識的時候,我們可以先換一個角度來思考這樣一個問題:假如微軟砸一億(YY一下),讓你去開發一門技術,用來做出各種各樣超炫的3D場景,你會大致怎麽下手:
   我不知道你具體會怎麽辦,但是一想到3D裏面各種各樣的形狀,顏色等等....我們肯定也都會在內心想,要設計出這麽技術,肯定要把這麽元素分開來搞。沒錯,微軟的那幫專家們也是這麽想的,大家英雄所見略同呀,哈哈。
   下面就一一來介紹這些需要分開的元素了

1. 類 Viewport3D

首先需要介紹的就是Viewport3D類。Viewport3D官方解釋是呈現 Viewport3D 元素的二維布局範圍內包含的三維內容。說的有些拗口,說白了就是首先你展現你的3D,你就必須有一個可以放你3D內容的盒子,存放你3D元素。本質和那些grid什麽的控件一樣。

這是csdn 的專業解釋:https://msdn.microsoft.com/zh-cn/library/system.windows.controls.viewport3d.aspx
屬性太多,就不一一解釋了,但是有2個元素要重點說名下。
假設一下,viewport是一個箱子,全密封的。裏面黑不溜秋,啥也看不見。但是裏面放了一些東西:比如說一把椅子。你要通過畫面感的東西,告訴別人裏面有什麽東西,而不是文字性的東西。
你就會想:這個箱子裏面那麽黑,至少需要有一盞等吧,才能看的清。沒錯,微軟的專家們也是這麽想的,於是他們就給Viewport裏面加一個Children————Light。

1.1 Light

但現實中Light也分好幾種呀,有一束光的形式的、也有手術臺上的那種無影燈,還有其它各種各樣的。
在WPF裏面,也有好幾種燈:AmbientLight、DirectionalLight、PointLight和SpotLight。   
    1、AmbientLight是不自然的光,會近似照亮整個場景。使用這種光看不到邊界。
    2、DirectionalLight定義了定向光。太陽光就是一種定向光,光線來自一邊,此時可以看到邊界和陰影。
    3、PointLight是一種位於指定位置的光,會照亮所有的方向。
    4、SpotLight照亮指定的方向。這個光定義了一個圓錐的形象,會得到一個發出光亮的區域。
具體實際開發過程中需要哪種燈光效果去看清箱子裏面的東西,大家就自己選了。

1.2 Camera

說到這,現在箱子裏面有了光,但是不行呀,因為箱子密不透風,還是從外面看不出來你裏面有什麽了。要是能在箱子上鑿一個洞,不僅能借到光,也能看清楚箱子裏面有什麽了。
鑿洞是個解決方法,但不是個好辦法,整點高科技的:Camera(攝像機);箱子上面裝了個攝像機。
Camera有了、但是問題又來了:這攝像機怎麽擺呢?這朝天看呢,還是朝地上。
要解決這個問題,就要用到Position(位置)、LookDirection(位置方向)、UpDirection(攝像機上面的方面)、FieldOfView(鏡頭角度)、NearPlaneDistance(近端距離)、FarPlaneDistance(遠端距離)。
1、Position:顧名思義就是一個空間的點(Point3D),來表示攝像機的位置。
2、LookDirection:就是攝像機鏡頭朝看的方向(Vector3D)。
3、UpDirection:就是攝像機上面的方向(Vector3D)。
4、FieldOfView:這個攝像機是一個單反,可以自動變焦的。而FileofView 就是攝像機調節焦距的參數。可以通過調節這個參數,來拉近或者放遠這些參數。
5、NearPlaneDistance:近端距離 
6、FarPlaneDistance:遠端距離

攝像機基本這樣愉快的設定好了。

2 類ModelVisual3D

箱子燈也有了,攝像機也有了,現在就差主角————箱子裏面的寶貝了,首先上場的就是ModelVisual3D。
ModelVisual3D,顧名思義,就是看到的3D模型。
構建一個3D模型,很顯然,首先要明確這個模型的現狀,然後再明確這個形狀的材質,也就是畫刷。

2.1 GeometryModel3D

GeometryModel3D類就是定義模型的幾何形狀的類。首先要明確一個概念:就是任何幾何形狀都可以用一定數量三角形來構成。比如說一個正方形就是2個三角形構成的。 就是按照這個思路完成的。
GeometryModel3D主要有geometry(幾何形狀)、和Material(材質)設定。
GeometryModel3D的geometry是MessGeometry3D(紋理幾何3D),(不要問我為什麽,我暫時也不知道,待我仔細需找找資料)
**MessGeometry3D是這一裏的重點了**。
MessGeometry3D有4個且有關鍵的屬性:Position(幾何內頂點的集合)、Normals(法向量集合)、TextureCoordinates(紋理坐標集合)、TrianglenIndices(三角形索引集合)。
1、Position:先說說這個頂點。
在wpf裏面,有一個xyz的三維坐標。如下圖所示:
![三維坐標](https://img-blog.csdn.net/20150328235600769)
一個幾個形狀參考這樣一個幾何圖形,構成相應的點(Point3D)的集合。如果一個正方形會有8個點。
P1(1 0 -1)
P2(-1 0 -1)
P3(-1 0 1)
P4(1 0 1)
P5(1 1 -1)
P6(-1 2 -1)
P7(-1 3 1)
P8(1 4 1)
(這些點,大家可以畫在一個草稿上)
2、TrianglenIndices:三角索引集合。
有了點的集合,但是如何將這些點構成一個個面呢,而且是構成我們想要的面呢?
只有當構成的面正確了,然後再能構成我們想要的幾何形狀。
三角形索引就是幫助我們構成面的。
三角形索引就是按照我們點的順序(從0開始)逆時針(以所需要面為正面)描出來。我們上面說了2個三角形可以構造一個正方形。所以一個長方體需要12個三角形。
023   012  014   154  165  126  276  247  037  074  456  467 

3、TextureCoordinates:紋理坐標用於確定將 Material 映射到構成網格的三角形的頂點的方式。
對於一個面,WPF裏面規定
左上角(0 0)           右上角(1 0)
左下角(0 1)           右下角(1 1)

比如這個立方體底部的面  正常的順序是 P1 P2 P3 P4  
也就是 01 10 11 01  
這個是正常的順序,

!了的樣這是就能可,果效示顯那 

4 Normals 法向量集合
學過幾何的人都知道立體幾何裏面有一個法向量,它是與說描述的面成一個垂直的關系。在這裏面也是與定義網格的每個三角形的面垂直的向量。 法向量用於確定是否亮顯給定三角形面。如果指定了三角形索引,則將考慮相鄰面來生成法向量。

Geometry3D的幾何紋理說完了,就是Material(材質)了。
這個比較簡單
有DiffuseMaterial 擴散材質,可以類比為普通的白石灰墻那種材質
SpecularMaterial 透視材質  可以類比為家裏普通的窗戶玻璃材質
EmissiveMaterial 放射性材質 額 這個家裏貌似都不太有  大家自行腦補吧

各個材質有畫刷屬性,通過畫刷屬性,可以為材質圖上不同的顏色、甚至是圖案畫刷等等。

通過完整為以上設置,及調整,基本就可以出來我們想要的3D圖形了。可能結構有些亂,我再來一張圖表示下:

![這裏寫圖片描述](https://img-blog.csdn.net/20150329005744356)

3 類Viewport2DVisual3D

上面描述的是重新繪制的3D模型作為內容、但是wpf也可以將其它普通控件,如Button、Image、TextBox變成3D立體呈現的效果。這個時候就需要接下來介紹的Viewport2DVisual3D.
與ModelVisual3D系統,也需要設置Geometry屬性(既是messgeometry3D),還有Matrail(材質)。
還有個visual屬性即我們需要立體呈現的控件元素了。


初稿先寫到這,示例代碼或者需要修改或者補充的到時再繼續完善。
2015年3月29日01:12:57

#WPF的3D開發技術基礎梳理