锯齿状的边缘和奇怪的阴影

时间:2012-11-17 14:27:11

标签: c# xna

我正在使用嵌入在WinForms中的XNA,从微软网站下载。并且已经注意到,当绘制模型时,一切看起来都不错,但是一旦我旋转相机,模型上的边缘就会开始变得锯齿状。这是我正在谈论的两张照片:

随着相机越接近目标,这一点就越明显。我用这个来绘制每个网格:

foreach (ModelMesh mesh in model.Meshes)
{
    foreach (BasicEffect effect in mesh.Effects)
    {
        effect.View = cam.view;
        effect.Projection = cam.projection;
        effect.World = mesh.ParentBone.Transform;
        effect.EnableDefaultLighting();
    }
    mesh.Draw();
}

有时如果我旋转模型,会出现一些奇怪的阴影。阴影甚至不会改变他们的“位置”,但仍然保持同样的状态。


编辑:所以我google了一下,看到启用MultiSampling应该摆脱锯齿状边缘。现在,有人知道如何在WinForms中执行此操作吗?

编辑2:关于后备缓冲区,我没有把它设置在任何地方,所以我猜它是应该的。 这是GraphicsDeviceService.cpp构造函数:

    GraphicsDeviceService(IntPtr windowHandle, int width, int height)
    {
        parameters = new PresentationParameters();

        parameters.BackBufferWidth = Math.Max(width, 1);
        parameters.BackBufferHeight = Math.Max(height, 1);
        parameters.BackBufferFormat = SurfaceFormat.Color;
        parameters.DepthStencilFormat = DepthFormat.Depth24;
        parameters.DeviceWindowHandle = windowHandle;
        parameters.PresentationInterval = PresentInterval.Immediate;
        parameters.IsFullScreen = false;

        graphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter,
                                            GraphicsProfile.Reach,
                                            parameters);
    }

此外,reset方法依次设置backBuffer。

编辑3: 我尝试将MultiSampleCount设置为更大的数字,但没有任何帮助,这里现在是两张正在发生的事情的图片。首先,我在某个地方实例化对象,然后我只移动相机。并且整个物体伸展并获得这些锯齿状边缘,如下图所示。这是相机移动代码:

http://img152.imageshack.us/img152/5204/normalu.png

http://img28.imageshack.us/img28/4434/movedright.png

KeyboardState state = Keyboard.GetState();

Vector3 v;

if (state.IsKeyDown(Keys.Up) || state.IsKeyDown(Keys.W))
    v = new Vector3(0, 0, 1) * moveSpeed;
else if (state.IsKeyDown(Keys.Down) || state.IsKeyDown(Keys.S))
    v = new Vector3(0, 0, -1) * moveSpeed;
else if (state.IsKeyDown(Keys.Left) || state.IsKeyDown(Keys.A))
    v = new Vector3(1, 0, 0) * moveSpeed;
else if (state.IsKeyDown(Keys.Right) || state.IsKeyDown(Keys.D))
    v = new Vector3(-1, 0, 0) * moveSpeed;
else if (state.IsKeyDown(Keys.PageUp))
    v = new Vector3(0, -1, 0) * moveSpeed;
else if (state.IsKeyDown(Keys.PageDown))
    v = new Vector3(0, 1, 0) * moveSpeed;
else
    v = new Vector3(0, 0, 0);

view *= Matrix.CreateTranslation(v);

相机视图和投影:

view = Matrix.CreateLookAt(cameraPos, Vector3.Zero, Vector3.Up);
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f), ratio, 0.5f, 50f);
在这种情况下,

cameraPos是0,0,10

编辑:影子 我finnaly得到了一个阴影问题的图片。正如你所看到的,每个网格都有自己的阴影,而不是只有一个阴影进入所有网格。

http://img843.imageshack.us/img843/8263/weirdshadowing.png

这是模型的自上而下视图。

1 个答案:

答案 0 :(得分:3)

嵌入在WinForms中的XNA的抗锯齿

这个问题实际上是this question的重复。

下载XNA/WinForms Sample here

GraphicsDeviceService类文件中,导航到构造函数:

GraphicsDeviceService(IntPtr windowHandle, int width, int height)
{
    parameters = new PresentationParameters();

    // Add this line
    // Increase the count to get higher quality anti-aliasing
    parameters.MultiSampleCount = 8;

    // More parameter settings and initialization
    // ...
}

您可以在下面的图片中看到差异:

with and without multisampling comparison


旧答案

标准XNA应用程序的抗锯齿

graphics.PreferMultiSampling = true;

按照此MSDN article中的说明为后备缓冲区启用消除锯齿功能。

PreferMultiSampling属性是GraphicsDeviceManager类的成员。

增加/降低质量

MultiSampleCount类的PresentationParameter属性可用于更改样本数。每个像素更多的样本意味着更少的伪像和更长的渲染时间。


进一步阅读多重采样


请注意,只有当问题的根源位于图形管道,更具体地说是光栅化器时,此解决方案才有效。

Nico Schertler所述,请确保在将其嵌入WinForms的过程中不会更改图像分辨率。如果边缘上的步骤不是一个像素宽,则表明问题来自于WinForms中纹理的呈现。

我无法解决阴影问题,因为很难从图像中猜出灯光设置。