天天看點

去除WPF中3D圖形的鋸齒

原文:

去除WPF中3D圖形的鋸齒

      理論上講PC在計算3D圖形的時候是無法避免不出現鋸齒的,因為3D圖形都是又若幹個三角形組成,如果3D圖形想平滑就必須建立多個三角形,你可以想象一下正5邊形和正100邊形哪個更接近圓形的道理一樣,這樣會大量消耗顯示卡的存儲空間或是從記憶體共享的存儲空間,導緻程式的整體性能降低,但如果三角形很少,顯示卡的解析度畢竟有限,就會出現鋸齒。最常見的處理方式在我們玩的3D遊戲裡都可以見到,就是所謂的反鋸齒功能。反鋸齒功能(反鋸齒加速齒輪)的作用是為了讓遊戲畫面中的棱角更平滑更圓潤。而在遊戲畫面中的3D遊戲裡面的反鋸齒選項中會有2X 4X 6X等是指你想開啟幾個反鋸齒加速齒輪管線,開的越多畫面越平滑圓潤,效果也就越好。但是它是以顯示卡的顯存資源的使用成正比的,如果遊戲記憶體資源的使用率高出了顯存或記憶體的極限,一般會導緻遊戲彈出或當機的發生。

      我們知道WPF中的圖形呈現都是通過顯示卡的GPU來進行計算處理的,是以改變顯示卡的3D平滑處理設定也可以消除鋸齒(比如設定為8X),但你會發現其他的問題又會出現,不僅程式運作變慢甚至視訊播放不了等。既然WPF誕生的時候已經強調了WPF不必關心顯示卡的問題,因為通過使用軟體計算而不依賴顯示卡提供的内在支援,WPF可以執行任何渲染操作,那麼應該可以通過程式來去除鋸齒,是以就不要打硬體的主意了。

     在程式中實作3D效果的時候,接觸最多的就是Viewport3D了,它是用來為三維可視内容提供呈現圖面的,這個類的一個屬性叫做3D Antialiasing,意思就是去除3D鋸齒,邊緣模式的預設值是Unspecified,先看看效果:

去除WPF中3D圖形的鋸齒

    你會發現微小的鋸齒仍然存在,消除鋸齒不是很明顯,還有一點不能容忍的是,一旦3D Antialiasing設定為Unspecified,系統就是多重取樣,整個程式就會卡,直接影響的是呈現速度,是以為了保證程式的流暢度,我們需要把3D Antialiasing的值設定為Aliased,就是将非文本(始終通過反失真效果來顯示文本對象,設定邊緣模式值不會對其産生影響)繪圖基元的邊緣呈現為鋸齒形邊緣,這樣就不會影響呈現速度,設定方法如下

XAML: <Viewport3D x:Name="myVisual" RenderOptions.EdgeMode="Aliased">

C#:RenderOptions.SetEdgeMode((DependencyObject)myVisual, EdgeMode.Aliased);

然後再看看效果:

去除WPF中3D圖形的鋸齒

     觀察一下會發現,和開啟了消除鋸齒功能的效果沒什麼差別,隻是程式不卡了,而且消除鋸齒的功能隻有在Vista和Windows7中才好用,對XP并不支援,可見

3D Antialiasing的方法仍然解決不了問題。

    說句公道話,上面的效果中那點鋸齒其實很微不足道,你要是用過iphone或itunes,很多App中也存在這樣的鋸齒,但這微小的瑕疵是可以容忍的,你在去看看那些大型的3D遊戲,鋸齒随處可見。盡管可以容忍但在WPF中仍有好方法可以去掉鋸齒的,方法非常簡單,沒有做不到,隻有想不到。

     既然産生鋸齒的位置都在邊緣(Edge),解決方法就在邊緣上,我們可以用Border執行個體作為3D模型的父容器,并把BorderBrush設定為Transparent,BorderThickness為2~3,這樣邊緣部分就變透明了,鋸齒也不見了,效果如下:

去除WPF中3D圖形的鋸齒

繼續閱讀