I have an image viewer created using WPF 3D graphics. The image quality is actually WORSE there, so I began to study this problem, created a simple application that displays an image using 2D graphics at the top of the window and the same image at the bottom using 3D graphics. I noticed that the image looks much worse on a 3D surface than on a 2D. Colors on a three-dimensional surface are less saturated and do not have clear boundaries. Notice that I applied linear raster scaling to the root grid. Another strange thing is that when I change the bitmap scaling mode to "Fant" or "NearestNeighbor", this affects the 2D graphics, but the image on the 3D surface remains ONE! I use the image for this sample with Height = 466px, Width = 490px. I slightly increase it in the code (both in 2D and in 3D) to see a decrease in the quality of scaling. Code:
<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; } } }
Thanks in advance for your help!
source share