最近几天我们在我们的体素引擎上工作了。如果我们绘制立方体,我们会遇到一些深度渲染问题。请参阅以下Youtube-Video:http://youtu.be/lNDAqO7yHBQ
我们已经搜索过这个问题并找到了不同的方法,但没有一个解决了我们的问题。
我们的LoadContent()
方法:
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
_effect = new BasicEffect(GraphicsDevice);
_vertexBuffer = new VertexBuffer(GraphicsDevice, Node.VertexPositionColorNormal.VertexDeclaration, _chunkManager.Vertices.Length, BufferUsage.WriteOnly);
_vertexBuffer.SetData(_chunkManager.Vertices); // copies the data from our local vertices array into the memory on our graphics card
_indexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), _chunkManager.Indices.Length, BufferUsage.WriteOnly);
_indexBuffer.SetData(_chunkManager.Indices);
}
我们的Draw()
方法:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;
// Set object and camera info
//_effect.World = Matrix.Identity;
_effect.View = _camera.View;
_effect.Projection = _camera.Projection;
_effect.VertexColorEnabled = true;
_effect.EnableDefaultLighting();
// Begin effect and draw for each pass
foreach (var pass in _effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.SetVertexBuffer(_vertexBuffer);
GraphicsDevice.Indices = _indexBuffer;
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _chunkManager.Vertices.Count(), 0, _chunkManager.Indices.Count() / 3);
}
base.Draw(gameTime);
}
我们的观看和投影设置:
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)Game.Window.ClientBounds.Width / Game.Window.ClientBounds.Height, 1, 500);
View = Matrix.CreateLookAt(CameraPosition, CameraPosition + _cameraDirection, _cameraUp);
我们使用Aaron Reed的书(http://www.filedropper.com/camera_1)中的相机(http://shop.oreilly.com/product/0636920013709.do)。
你有没有看到我们错过的东西?或者你有想法解决这个问题吗?
答案 0 :(得分:0)
今天我们就这个话题进行了研究。我们原始代码中体素的坐标是arround(X:600'000,Y:750,Z:196'000)。在我们将所有体素重新定位到更接近零点(X:0,Y:0,Z:0)之后,所述问题消失了。我们假设这与XNA使用的datatyp float有关。根据MSDN(http://msdn.microsoft.com/en-us/library/b1e65aza.aspx),浮点数的精度只有7位数。我们的结论是,如果你将体素放在坐标上,精度为7位,并且因为XNA的DepthBuffer与浮点数一起工作,你就会得到我们上面描述的效果。
也许有人会证实我们的假设吗?
谢谢!
答案 1 :(得分:0)
是的,这是游戏中众所周知的问题,特别是大型世界模拟,如飞行和太空模拟。基本上当相机移动距离原点太远时,出现浮点不准确性,这会造成严重破坏,特别是在旋转期间。
解决方案是一种称为floating origin的方法,而不是移动眼睛,而是基本上移动宇宙。本文适用于Unity3D,但由于它是.net,您可以将其转换为XNA。您可以阅读更多相关信息 here in this excellent article
此外,只有在z-buffer中可以挤入有限数量的位,同时在非常接近和非常远的同时观看。为此,您需要使用对数z缓冲区而不是1:1。 Want to know more?