2011-04-02 94 views
4

我有一個使用WPF 3D圖形創建的圖像查看器。圖像質量真的很糟糕,所以我開始研究這個問題,創建了一個簡單的應用程序,它使用窗口頂部的2D圖形顯示圖像,並使用3D圖形在底部顯示相同的圖像。我注意到圖像在3D表面上比在2D上看起來糟糕得多。 3D表面上的顏色飽和度較低,並且沒有清晰的邊界。請注意,我將線性位圖縮放模式應用於根網格。其他奇怪的是,當我將位圖縮放模式更改爲「Fant」或「NearestNeighbor」時,會影響2D圖形,但3D圖像上的圖像仍然會保持不變!我使用Height = 466px,Width = 490px的示例使用圖像。我在代碼中縮小了它(包括2D和3D實現),以查看縮放質量下降情況。代碼是:WPF中3D表面問題的圖像縮放質量

<Window x:Class="Scaling3DSample.Window2" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="340"> 
     <Grid x:Name="backgroundGrid"> 
      <Grid.RowDefinitions> 
       <RowDefinition /> 
       <RowDefinition /> 
      </Grid.RowDefinitions> 
     </Grid> 
</Window> 

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Media.Media3D; 
using System.Windows.Shapes; 
    namespace Scaling3DSample 
    { 
     public partial class Window2 : Window 
     { 
      private static double _distanceFromCamera = 0.62618; 

      public Window2() 
      { 
       InitializeComponent(); 
       RenderOptions.SetBitmapScalingMode(backgroundGrid, BitmapScalingMode.Linear); 
       Create2DGraphics(); 
       // THE SAME IMAGE ON 3D SURFACE LOOKS MUCH WORSE 
       Create3DGraphics(); 
      } 

      private void Create2DGraphics() 
      { 
       Rectangle exampleRectangle = new Rectangle(); 
       Grid.SetRow(exampleRectangle, 0); 

       exampleRectangle.Width = 335; 
       exampleRectangle.Height = 317; 
       exampleRectangle.Fill = GetBrush(); 
       backgroundGrid.Children.Add(exampleRectangle); 
      } 

      private void Create3DGraphics() 
      { 
       Viewport3D mainViewPort3D = new Viewport3D(); 
       Grid.SetRow(mainViewPort3D, 1); 

       mainViewPort3D.Camera = new PerspectiveCamera { LookDirection = new Vector3D(-1, 0, 0), UpDirection = new Vector3D(0, 0, 1), FieldOfView = 77.0942 }; 
       mainViewPort3D.Children.Add(new ModelVisual3D { Content = new AmbientLight() }); 

       MeshGeometry3D geometry3D = new MeshGeometry3D(); 

       Point3D topLeft = new Point3D(-_distanceFromCamera, 0.5, -0.5); 
       Point3D bottomRight = new Point3D(-_distanceFromCamera, -0.5, 0.5); 

       geometry3D.Positions.Add(bottomRight); 
       geometry3D.Positions.Add(new Point3D(-_distanceFromCamera, topLeft.Y, bottomRight.Z)); 
       geometry3D.Positions.Add(new Point3D(-_distanceFromCamera, bottomRight.Y, topLeft.Z)); 
       geometry3D.Positions.Add(topLeft); 

       geometry3D.TriangleIndices.Add(1); 
       geometry3D.TriangleIndices.Add(0); 
       geometry3D.TriangleIndices.Add(2); 

       geometry3D.TriangleIndices.Add(2); 
       geometry3D.TriangleIndices.Add(3); 
       geometry3D.TriangleIndices.Add(1); 

       geometry3D.TextureCoordinates.Add(new Point(0, 0)); 
       geometry3D.TextureCoordinates.Add(new Point(1, 0)); 
       geometry3D.TextureCoordinates.Add(new Point(0, 1)); 
       geometry3D.TextureCoordinates.Add(new Point(1, 1)); 

       Material material = new DiffuseMaterial(GetBrush()); 

       ModelVisual3D modelForGeometry = new ModelVisual3D { Content = new GeometryModel3D(geometry3D, material) }; 
       mainViewPort3D.Children.Add(modelForGeometry); 
       backgroundGrid.Children.Add(mainViewPort3D); 
      } 

      private ImageBrush GetBrush() 
      { 
      // put any other image URI here, image Height = 466px, Width = 490px 
       ImageBrush brush = new ImageBrush(new BitmapImage(new Uri("lion.jpg", UriKind.Relative))); 
       brush.Stretch = Stretch.Fill; 
       return brush; 
      } 
     } 
    } 

在此先感謝您的幫助!

+0

有一個細微的差別 - 但不要忘記,渲染3D圖形所涉及的變換比2D更多,圖像,幾何和視覺透過透視變換。 – ChrisF 2011-04-02 18:19:45

+0

@ChrisF,感謝您的評論。當我使用此代碼顯示高清晰度照片時,差異更加顯着。特別是當我縮小圖像時。 – 2011-04-02 19:42:54

回答

1

那麼還有其他一些變數需要考慮。

儘管WPF提出了更好的外觀要求,但您的顯卡設置可能會迫使插值模式下降。 WPF的3D在第2層硬件上進行了硬件加速,因此請檢查您的驅動程序的控制軟件。 WPF可能無法提出更好的請求!

嘗試在應用程序和圖形卡設置中啓用抗鋸齒功能。

+0

嗨@djdanlib,感謝您的回放。我怎樣才能改變我的視頻卡的插值模式?我認爲在所有客戶端機器上配置視頻卡會很困難,有沒有更改WPF插值模式的選項,而不是顯卡?感謝你的幫助。 – 2011-04-05 10:15:43

+0

似乎無法在WPF [關於社交msdn的討論](http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/)中關閉消除鋸齒(始終開啓) 1ad9a62a-d1a4-4ca2-a950-3b7bf5240de5 /) – 2011-04-05 10:36:09

+1

這將是在顯卡的軟件中完成的每臺機器設置(每個製造商都不同),並且通常需要用戶對其進行設置。我從來沒有見過它默認強制它降到最低的設置,但只有當有人進入並手動調整它在更多的FPS的地方。如果你沒有調整你的GFX設置,它可能不會這麼做。該BitmapScalingMode調用看起來像您將爲您的WPF應用程序設置它的方式。嘿,這值得一試!我找到了一個論壇帖子,可以幫助你:http://forums.silverlight.net/forums/p/82277/223689.aspx – djdanlib 2011-04-05 14:37:24

1

只是猜測:你沒有定義任何燈光,也沒有任何法線。有時會導致比您期望的更暗的圖像。

+0

嗨@Erno,其實我正在使用環境光。 'code'mainViewPort3D.Children.Add(new ModelVisual3D {Content = new AmbientLight()});'code'。 – 2011-04-03 17:44:36