“奇怪”;fuzz";在XNA 4.0中在平面上渲染纹理时

“奇怪”;fuzz";在XNA 4.0中在平面上渲染纹理时,xna,Xna,我刚刚开始使用XNA,我确信我遗漏了一些非常简单的东西。我画了一个四边形的平面。在这个平面上,我包裹了一个2D纹理。近距离观察,纹理看起来很好,但当我移动相机时,我看到一堆白色的人工制品到处都是。当我靠近他们时,他们消失了。我猜这是一个抽样问题或类似的问题,但我被卡住了 首先,我创建了一个quadrawer类来为我绘制平面。它源自DrawableGameComponent 四抽屉: class QuadDrawer : DrawableGameComponent { private

我刚刚开始使用XNA,我确信我遗漏了一些非常简单的东西。我画了一个四边形的平面。在这个平面上,我包裹了一个2D纹理。近距离观察,纹理看起来很好,但当我移动相机时,我看到一堆白色的人工制品到处都是。当我靠近他们时,他们消失了。我猜这是一个抽样问题或类似的问题,但我被卡住了

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

四抽屉:

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);
    }

  }
一旦将对象添加到我的Components集合中,就会调用QuadDrawer的Draw方法,一切都应该正常。这是我所看到的图像。注意:这应该是纯灰色,浅色线以网格模式运行。当围绕曲面移动摄影机时,白色瑕疵看起来会移动,但当靠近时会消失

下面是显示白色工件的图片:

这是一个特写镜头,展示了它的外观:

下面是另一张图片,显示了从远处看它会变得多么糟糕:

从远处看应该是这样的:

这幅画不是最好的,但你可以看到我在说什么。当摄像机移动时,情况变得非常糟糕。我在其他地方见过这种纹理,效果很好。知道会是什么吗

如果你需要的话,我很乐意提供更多的信息

谢谢


-斯科特

这看起来像是一个各向异性过滤问题。我注意到您确实有
GraphicsDevice.SamplerStates[0]=SamplerState.AnisotropicWrap正在使用中。我建议看看肖恩·哈格里夫斯,特别是下面几行

device.SamplerStates[0].MinFilter = TextureFilter.Anisotropic;
device.SamplerStates[0].MagFilter = TextureFilter.Linear;
device.SamplerStates[0].MipFilter = TextureFilter.Linear;
device.SamplerStates[0].MaxAnisotropy = <n>;
代码片段感谢over at,这是另一个从XNA大师那里获得帮助的好地方:)


HTH

各向异性过滤将无济于事。您最好的解决方案(虽然不便宜)是使用,这将最终解决您的问题,但相当昂贵,或者,这将解决您的问题,取决于您使用的正方形几何体


根据我个人的经验,在任何情况下,多重采样通常都可以保留,因为现代图形卡确实能够以不太高的成本渲染它,除非您正在构建一个非常GPU密集的应用程序\游戏。此外,超级采样并非完全不可能,尽管使用起来相当昂贵,原因与上述相同,但需要进行测试,以确保不会对性能造成太大的损失。

首先,您需要为纹理启用mipmap。如果它只是一个独立资产,您可以在解决方案资源管理器中选择它,按F4键进入属性,展开“Content Processor”节点并将“Generate Mipmap”设置为true

。看看那篇文章中这两张图片之间的区别:

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

然后,如果你打算以这样的倾斜角度观看,你需要启用各向异性过滤(Layric在他的回答中解释了如何)。这张来自的图像说明了各向异性过滤的用途-请注意它是如何水平“取消模糊”背景的(这是由mipmap引起的)



(来源:)

尽管这些工件对您来说可能很明显,但我仍然无法看到您描述的问题。您是否能够获得更好的示例图像并圈出所述工件的实例?谢谢。我添加了另一张图片,显示得更好。所有的白线都是不应该出现的。在新图像中,您可以看到当白色网格线远离相机时,它们是如何开始旋转的。我将上传另一张照片,我希望它看起来像什么。顺便说一下,我应用的任何纹理都会发生这种情况,不仅仅是这个。谢谢@Layouric-我在最底部添加了另一幅图像,显示了从远处看场景应该是什么样子。任何帮助都是非常感谢的…感谢链接。我通读了这篇博文,应用了不同类型的过滤器——没有一种过滤器解决了我的问题。即使移除各向异性包裹取样器,我仍然会得到伪影。我只是对这些东西还不太了解,还没有找到这一个…更新了一些建议@ScottI相信4.0取消了basicefect.Begin()和basicefect.CommitChanges()。但是,我确实应用了您在上面建议的过滤器(使用4.0语法),我仍然存在相同的问题。我将从QuadDrawer类中取出所有代码,并将其直接添加到我的Game类中,以查看该类是否存在问题。谢谢你的帮助。如果你有更多的建议。。。。我很想听。你在效果循环中分配了过滤器吗?虽然各向异性过滤本身没有帮助(尽管如果使用正确会有帮助),但超级采样只会减少问题,而不会解决问题。多重采样只有在这是几何体的情况下才有帮助——OP使用的是纹理(同样,它只会减少问题)。请参阅我的答案中链接的文章,以更深入地解释为什么这两种解决方案不起作用。这完全解决了我的问题。显然,我还有很多东西要学。谢谢
device.SamplerStates[0].MinFilter = TextureFilter.Anisotropic;
device.SamplerStates[0].MagFilter = TextureFilter.Linear;
device.SamplerStates[0].MipFilter = TextureFilter.Linear;
device.SamplerStates[0].MaxAnisotropy = <n>;
// inside draw perform any other required draw code  

// Call begin on the basic effect and on the pass to initialize BasicEffect's render settings  
basicEffect.Begin();  
basicEffect.CurrentTechnique.Passes[0].Begin();  

// Set your desired filter settings  
GraphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Anisotropic;  
GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Anisotropic;  
GraphicsDevice.SamplerStates[0].MipFilter = TextureFilter.Linear;  
GraphicsDevice.SamplerStates[0].MaxAnisotropy = 16;  

// Commit the changes to basic effect so it knows you made modifications  
basicEffect.CommitChanges();  

// Now perform you rendering to see Anisotropic filtering in effect