필자가 작성한 WPF 응용 프로그램에서 이상한 동작이 발생합니다. PerspectiveCamera.PositionProperty의 Point3DAnimation이라는 카메라 위치에서 애니메이션을 실행하면 응용 프로그램 내부에서 실제로 깜박 거리는 결함이 발생합니다. 3D로 렌더링 된 오브젝트는 특정 프레임에서 사라지는 것처럼 보이고 창의 배경이 보이도록합니다.Viewport3D에서 애니메이션 중 WPF가 깜박입니다.
내 컴퓨터의 문제를 보여주기 위해 아래의 간단한 샘플 응용 프로그램을 작성했습니다. 그것을 사용하려면 컴파일하고 화살표 위아래 화살표를 사용하여 확대 및 축소하십시오. 문제는 컴퓨터에서 반복적으로 발생합니다. 확대 또는 축소하려고 할 때마다 애니메이션이 진행되는 동안 오브젝트가 깜박이고 애니메이션이 완료되면 다시 '단색'이됩니다.
저는 Windows 7 32 비트를 실행 중이며 NVIDIA GeForce 8600GT를 사용하고 있습니다. 다음은 몇 가지 흥미로운 세부 사항입니다 :
1) 하드웨어와 관련된 것 같습니다. 나는 WPF 포럼에 게시물을 올렸고 한 사용자는 모든 것이 훌륭하다고 말했습니다. 나는 몇몇 친구에게 그것을 시도 해달라고 부탁했다. 그리고 나는 경험하고있는 정확하게 같은 깜박 거림을보고했다. 그리고 다른 것은 모든 것이 멋지게 보인다고 말했다.
2) 수직 동기화를 강제하고 NVIDIA 제어판을 통해 트리플 버퍼링을 활성화해도 문제가 해결되지 않습니다.
3) 애니메이션의 원하는 FPS를 줄이면 문제가 크게 개선됩니다. 낮은 프레임 속도 (예 : 5FPS)에서는 깜박임이 사라지지만 애니메이션은 끔찍한 것처럼 보입니다. 아래에서 제공하는 샘플 애플리케이션은 쿼드에 매핑 된 단일 이미지 만 표시하므로 처리 능력의 문제라고 생각하지 않습니다.
4)이 문제는 가시 창 외부 외부의 다각형 정점과 직접적으로 관련되어있는 것 같습니다.. 프로그램의 closeDist 값을 4로 설정하면 (즉 확대/축소 되어도 오브젝트가 윈도우 내에 완전히 들어갈 때도) 이 깜박이지 않습니다. 그러나 closeDist를 늘리 자마자 'zoomed in'상태가 꼭지점이 창 밖으로 나가는 값에 도달하면 깜박임이 발생합니다. 깜박임이 closeDist를 증가시킬 때 점차적으로 으로 나타납니다. 9.8의 값 (카메라의 NearPlaneDistance가 객체를 완전히 잘라 버리기 직전)에서 깜박임이 최악입니다.
샘플 코드는 다음과 같습니다.
MainWindow.xaml :
<Window x:Class="WPFFlickerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
KeyDown="Window_KeyDown">
<Grid>
<Viewport3D Name="Viewport">
<Viewport3D.Camera>
<PerspectiveCamera LookDirection="0,0,1" FieldOfView="70" x:Name="viewportCam" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
</Window>
MainWindow.xaml.cs를 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation;
namespace WPFFlickerTest
{
public partial class MainWindow : Window
{
// time the camera animation takes to complete
private const double animTime = 0.25;
// path to an image to use (assuming it's 1920x1200 or 1.6 aspect ratio)
private const string imagePath = "C:/Windows/Web/Wallpaper/Windows/img0.jpg";
// far and close camera distances
private const double closeDist = 8, farDist = 10;
// chosen to align with aspect ratio of the image
private const double halfW = 4.8, halfH = 3;
public MainWindow()
{
InitializeComponent();
Model3DGroup modelGroup = new Model3DGroup();
// set up the mesh
MeshGeometry3D mesh = new MeshGeometry3D();
mesh.Positions.Add(new Point3D(-halfW, halfH, farDist));
mesh.Positions.Add(new Point3D(halfW, halfH, farDist));
mesh.Positions.Add(new Point3D(halfW, -halfH, farDist));
mesh.Positions.Add(new Point3D(-halfW, -halfH, farDist));
// set up triangle indices
mesh.TriangleIndices = (Int32Collection)new Int32CollectionConverter().ConvertFromString(
"0,1,2 2,3,0");
// set up texture coords
mesh.TextureCoordinates = (PointCollection)new PointCollectionConverter().ConvertFromString(
"1,0 0,0 0,1 1,1");
// set up the brush
ImageBrush brush = new ImageBrush(new BitmapImage(new Uri(imagePath, UriKind.Relative)));
// create a geometry model based on the mesh and give it a material based on an image
GeometryModel3D geom = new GeometryModel3D(mesh, new DiffuseMaterial(brush));
// add the object
modelGroup.Children.Add(geom);
// we should have filled in our objects now
// so we'll just add them to the viewport
ModelVisual3D modelVisual = new ModelVisual3D();
modelVisual.Content = modelGroup;
Viewport.Children.Add(modelVisual);
}
// react to keypresses
private void Window_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
// move the camera to the centre
case Key.Down: AnimateTo(new Point3D(0, 0, 0)); break;
// move the camera to the currently targeted image
case Key.Up: AnimateTo(new Point3D(0, 0, closeDist)); break;
}
}
// animate to a given position
void AnimateTo(Point3D position)
{
Point3DAnimation camPosAnim = new Point3DAnimation(position, TimeSpan.FromSeconds(animTime));
viewportCam.BeginAnimation(PerspectiveCamera.PositionProperty, camPosAnim);
}
}
}
그냥 줘서 나에게 잘 어울리 네요. 실제로 하드웨어와 관련이 있다는 당신의 직감이 정확합니다. 나는 랩톱에있다 ... 평범한 것 ... 아무것도 실행하지 않는다. .NET 3.5 SP1; DirectX/Direct3D를 업데이트하셨습니까? –
@Aaron 우수 제안. 최신 DirectX 런타임을 얻으려고했는데 이미 새로운 버전이나 동등한 버전이 있다고 들었습니다. dxdiag는 DirectX 11을 실행하는 것을 보여줍니다. 아래에 게시 할 또 다른 재미있는 음식을 발견했습니다. – aardvarkk
@aardvarkk 나는 9.0c에있다 ... –