在XNA 4.0中在平面上渲染纹理时奇怪的"模糊"

Sco*_*ott 5 xna

我刚刚开始使用XNA,我确信我错过了很简单的东西.我有一架四轮飞机,我画的是地面.在这个平面上,我包裹了一个2D纹理.纹理看起来很近,但是当我移动相机时,我看到整个地方都有一堆白色的文物.当我靠近他们时,他们消失了.我猜这是一个抽样问题或类似的东西,但我被卡住了.

首先,我创建了一个QuadDrawer类来为我绘制平面.它源自DrawableGameComponent.

QuadDrawer:

class QuadDrawer : DrawableGameComponent
  {
    private string _textureName;
    private Texture2D _texture;
    private BasicEffect _effect;

    private float _size = 100;

    private VertexPositionNormalTexture[] _vertices;
    private int[] _indices;

    public QuadDrawer(Game game, float size, string textureName)
      : base(game)
    {
      this._size = size;
      this._textureName = textureName;
    }

    public override void Initialize()
    {
      BuildVertices();
      base.Initialize();
    }

    private void BuildVertices()
    {
      _vertices = new VertexPositionNormalTexture[4];
      _indices = new int[6];

      _vertices[0].Position = Vector3.Forward + Vector3.Left;
      _vertices[0].TextureCoordinate = new Vector2(0.0f, 1.0f);
      _vertices[1].Position = Vector3.Backward + Vector3.Left;
      _vertices[1].TextureCoordinate = new Vector2(0.0f, 0.0f);
      _vertices[2].Position = Vector3.Forward + Vector3.Right;
      _vertices[2].TextureCoordinate = new Vector2(1.0f, 1.0f);
      _vertices[3].Position = Vector3.Backward + Vector3.Right;
      _vertices[3].TextureCoordinate = new Vector2(1.0f, 0.0f);

      for (int i = 0; i < _vertices.Length; i++)
      {
        _vertices[i].Normal = Vector3.Up;
        _vertices[i].Position *= _size;
        _vertices[i].TextureCoordinate *= _size;
      }

      _indices[5] = 0; _indices[4] = 1; _indices[3] = 2;
      _indices[2] = 2; _indices[1] = 1; _indices[0] = 3;
    }

    protected override void LoadContent()
    {
      _texture = this.Game.Content.Load<Texture2D>(_textureName);
      _effect = new BasicEffect(this.GraphicsDevice);
      _effect.EnableDefaultLighting();
      _effect.PreferPerPixelLighting = true;
      _effect.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f);

      _effect.World = Matrix.Identity;
      _effect.TextureEnabled = true;
      _effect.Texture = _texture;

      base.LoadContent();
    }

    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
    }

    public override void Draw(GameTime gameTime)
    {
      MyGame game = this.Game as MyGame;

      GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicWrap;
      GraphicsDevice.DepthStencilState = DepthStencilState.Default;

      _effect.View = game.Camera.ViewMatrix;
      _effect.Projection = game.Camera.ProjectionMatrix;

      foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
      {
        pass.Apply();

        GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, _vertices, 0, 4, _indices, 0, 2);
      }
      base.Draw(gameTime);
    }

  }
Run Code Online (Sandbox Code Playgroud)

从我的主要Game类的Initialize()方法,我只是实例化这个对象并传入我想要使用的GameObject,Size和Texture名称:

_floor = new QuadDrawer(this, 100.0f, "Textures/checker");
  this.Components.Add(_floor);
Run Code Online (Sandbox Code Playgroud)

一旦将对象添加到我的Components集合中,我的QuadDrawer的Draw方法就会被调用,并且一切都应该是好的.这是我所看到的图像.请注意,这应该是纯灰色,浅色线以网格图案运行.当您将相机移动到表面时,白色瑕疵似乎会移动,但当您靠近时会消失.

这是显示白色文物的图片:

模糊

这是一个近距离显示它应该如何看起来: 特写

这是另一张图片,展示了远距离有多糟糕: 更好地了解问题

这是从远处看它应该是什么样的: 在此输入图像描述

图片不是最好的,但你可以看到我在说什么.当相机移动时,它变得非常糟糕.我已经看到在其他地方使用这种纹理,它工作正常.知道它可能是什么?

如果您需要,我很乐意提供更多信息.

谢谢,

斯科特

And*_*ell 6

首先,您需要为纹理启用mipmap.如果它只是一个独立的资产,您可以在解决方案资源管理器中选择它,按F4进入属性,展开"内容处理器"节点并将"生成Mipmap"设置为true.

Shawn Hargreaves的这篇文章解释了为什么.看看那篇文章中这两张图片之间的区别:

http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-70-20-metablogapi/2388.image_5F00_401AFB8B.png

http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-70-20-metablogapi/6518.image_5F00_1B896E07.png

(看起来很像你的示例图片,不是吗?)

然后,如果你要以这样的倾斜角度观看,你需要启用各向异性过滤(Layoric在他的回答中解释了如何).来自维基百科的这张图片说明了各向异性过滤的用途 - 注意它是如何水平地"钝化"背景(由mipmap引起的).

http://upload.wikimedia.org/wikipedia/en/c/c0/Anisotropic_compare.png