1. 程式人生 > >【WPF】三維模型中的“照相機”

【WPF】三維模型中的“照相機”

聲明 mesh 妹子 .com 看到了 指向 世界 png per

WPF 部分支持三維模型,為啥說是部分支持?畢竟 WPF 的側重點還是在應用開發上,雖然也有些遊戲是用 WPF 開發的,不過,老周想啊,如果真要開發遊戲,最好用專門的框架,WPF 應當用於開發應用功能的。不過,動畫、三維建模這些支持可以作為輔助,尤其是在 UI 上,適當地,可以增強一下。當然,不要為了裝逼,弄得不倫不類的,那樣就是主次不分了,現在有不少軟件就是主次不分的。

在 WPF 中,要呈現三維模型,需要用到 Viewport3D ,它是三維對象的總容器,所有三維對象都應該放在這個容器中。本文老周不介紹三維對象的樹結構,而是重點說說 Viewport3D 的一個重要配件——照相機。

其實,這個“照相機”,與我們現實世界中的照相機差不多,它是我們觀察三維模型的一個入口,就好比我們從真實相機中的取景器去觀察被攝對象一樣,由於相機的視角廣度有限(哪怕是廣角鏡頭也是有限的),現實的被攝物體可以無限延展,但是,你在取景器中看到的只能是局部。道理也是一樣的,在 WPF 的三維模型中,Camara 只是設定我們能看到三維對象的局部,而維對象本身也可能是無限延展的。

Viewport3D 對象有個 Camera 屬性,用來設置一個合適的相機實例。照相機可以分為兩大類:

第一類,MatrixCamera,它通過一個矩陣來描述照相機的參數,這個估計用得不多,因為挺復雜的,反正老周是不知道怎麽用的。

第二類,ProjectionCamera,即帶投影透視效果的照相機,它派生出兩款相機,註意啊,不是佳能和尼康,是 PerspectiveCamera 和 OrthographicCamera。PerspectiveCamera相機比較好解,因為它是帶透視效果的,這也符合我們靈長目類動物的視覺特征——離得近的物體看起來會大一些,離得遠的物體會小一些,當然了,前提是物體大小接近,不然,這太陽比月球大太多了,所以,哪怕太陽離我們更遠,看起來也比月亮大。而 OrthographicCamera 呢,它不太符合咱們靈長目動物的視覺特征,因為使用這個照相機後,所視物體就變成了正交,即不存在透視效果,沒有距離之別,不管遠的還是近的,都一樣大。人要是能做到像正交鏡頭這樣就好了,不管親疏都一視同仁。有時候,人真的還不如代碼友好,因為有些人會算計你,但代碼不會,雖然有時候,代碼會耍性子,讓你又愛又恨,但是,它待你是真誠的,而人呢,也許只有少部分人能做得到,社會太缺誠信。

嗯,介紹完了幾類照相機,相信大夥一定想看看效果。行,老周也想,要不,咱們試試。

為了簡單,老周只建了一個正方體,而且這個正方體是衣裳不整的,只圍了一條裙子,僅僅聲明了左、前、右三個面。

        <Viewport3D>
            ……
            <!-- 模型,三個面 -->
            <ModelVisual3D>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <GeometryModel3D>
                            <GeometryModel3D.Geometry>
                                <MeshGeometry3D Positions="-2,4,0 -2,0,0 -2,0,4 -2,4,4" TriangleIndices="0,1,2,0,2,3"/>
                            </GeometryModel3D.Geometry>
                            <GeometryModel3D.Material>
                                <DiffuseMaterial Brush="Green"/>
                            </GeometryModel3D.Material>
                        </GeometryModel3D>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <GeometryModel3D>
                            <GeometryModel3D.Geometry>
                                <MeshGeometry3D Positions="-2,4,4 -2,0,4 2,0,4 2,4,4" TriangleIndices="0,1,2,0,2,3"/>
                            </GeometryModel3D.Geometry>
                            <GeometryModel3D.Material>
                                <DiffuseMaterial Brush="Blue"/>
                            </GeometryModel3D.Material>
                        </GeometryModel3D>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <GeometryModel3D>
                            <GeometryModel3D.Geometry>
                                <MeshGeometry3D Positions="2,4,4 2,0,4 2,0,0 2,4,0" TriangleIndices="0,1,2,0,2,3"/>
                            </GeometryModel3D.Geometry>
                            <GeometryModel3D.Material>
                                <DiffuseMaterial Brush="Red"/>
                            </GeometryModel3D.Material>
                        </GeometryModel3D>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </ModelVisual3D>
            <!-- 燈光,用來照亮模型,不然就全黑一片了 -->
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <AmbientLight Color="Purple"  />
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D>

AmbientLight 指的是環境光,即可以照亮整個模型的光,如果用 PointLight ,就是點光,類似於一個小燈泡,小蠟燭,只能照亮一點點空間。Color屬性指定了這燈光是紫色的,紫光可以誘捕害蟲,所以就用紫光了。

好,重點來了,我們先看看正交照相機。

        <Viewport3D>
            <Viewport3D.Camera>
                <OrthographicCamera Position="16,2,18" LookDirection="-1,0,-1" Width="10" />
            </Viewport3D.Camera>
           ……
        </Viewport3D>

Position 是指定照相機的位置,註意Z軸的坐標,如果Z軸值大於模型的Z軸值,那麽鏡頭就在物體前面,反之在物體後面。因此,你可以設置 LookDirection 來調整相機的方向,Position是相機的位置,就好比你站在某個點拍照;而LookDirection是相機看的方向,就像你拿著相機可以拍你前面的妹子,也可以拍你左邊的大爺,或者拍與你成30度夾角處的大叔。LookDirection指定你朝哪兒看。

如果相機位於物體前方,LookDirection 的Z軸值要小於0,因為Z軸的負方向是指向屏幕內部的,只有朝著負方向,才能看到物體;如果相機位於物體背面,那麽Z軸的值就要大於0,就樣才會朝向屏幕外部,看到物體。

正交相機看到的正方體如下圖所示。

技術分享

這是正方體的前面和側面,但是,你都看到了,兩個面一樣大,按理說,正面應該要離我們近一些,但是,正交相機是不考慮這個的,在它眼中,世界都是平的。

下面我們再換一個透視效果的相機。

        <Viewport3D>
            <Viewport3D.Camera>
                <PerspectiveCamera Position="10,5,10" LookDirection="-2.5,-1,-2" />
            </Viewport3D.Camera>
            ……
        </Viewport3D>

相機位於物體的左前方,並且朝著物體的右下方觀察。

此時,如下圖所示,你會看到透視效果。

技術分享

也許,這個更符合我們在現實世界中的觀察效果。

好了,又是開飯時間,今天就聊到這裏吧,有空,改天咱們泡上一壺龍井茶,繼續聊。

【WPF】三維模型中的“照相機”