我刚刚开始使用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方法就会被调用,并且一切都应该是好的.这是我所看到的图像.请注意,这应该是纯灰色,浅色线以网格图案运行.当您将相机移动到表面时,白色瑕疵似乎会移动,但当您靠近时会消失.
这是显示白色文物的图片:
这是一个近距离显示它应该如何看起来:
这是另一张图片,展示了远距离有多糟糕:
这是从远处看它应该是什么样的:
图片不是最好的,但你可以看到我在说什么.当相机移动时,它变得非常糟糕.我已经看到在其他地方使用这种纹理,它工作正常.知道它可能是什么?
如果您需要,我很乐意提供更多信息.
谢谢,
斯科特
首先,您需要为纹理启用mipmap.如果它只是一个独立的资产,您可以在解决方案资源管理器中选择它,按F4进入属性,展开"内容处理器"节点并将"生成Mipmap"设置为true.
Shawn Hargreaves的这篇文章解释了为什么.看看那篇文章中这两张图片之间的区别:
(看起来很像你的示例图片,不是吗?)
然后,如果你要以这样的倾斜角度观看,你需要启用各向异性过滤(Layoric在他的回答中解释了如何).来自维基百科的这张图片说明了各向异性过滤的用途 - 注意它是如何水平地"钝化"背景(由mipmap引起的).
http://upload.wikimedia.org/wikipedia/en/c/c0/Anisotropic_compare.png