0

过去几天我们研究了体素引擎。如果我们绘制立方体,我们会遇到一些深度渲染问题。请参阅以下 Youtube 视频:http: //youtu.be/lNDAqO7yHBQ

我们已经沿着这个问题搜索并找到了不同的方法,但它们都没有解决我们的问题。

  • GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.CornflowerBlue, 1.0f, 0);
  • GraphicsDevice.BlendState = BlendState.Opaque;
  • GraphicsDevice.DepthStencilState = DepthStencilState.Default;
  • GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

我们的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://shop.oreilly.com/product/0636920013709.do )中的相机 ( http://www.filedropper.com/camera_1 )。

你看到我们遗漏的东西了吗?或者你有解决这个问题的想法吗?

4

2 回答 2

0

是的,这是游戏中的一个众所周知的问题,尤其是大型世界模拟,例如飞行和太空模拟。本质上,当相机离原点太远时,会出现浮点不准确性,这会造成严重破坏,尤其是在旋转过程中。

解决方案是一种称为浮动起源的方法,在这种方法中,您实际上是在移动宇宙,而不是移动眼睛。本文适用于 Unity3D,但由于它是 .net,您可以将其转换为 XNA。你可以在这篇优秀的文章中阅读更多关于它的信息

此外,您只能在 z 缓冲区中挤入有限数量的位,同时查看非常近和非常远的位置。为此,您需要使用对数 z 缓冲区而不是 1:1。想知道更多?

前段时间我在这里研究我的太空模拟时,我在博客上写过它。

于 2014-10-12T16:03:42.290 回答
0

今天我们研究了这个话题。我们原始代码中体素的坐标是 arround (X:600'000, Y:750, Z:196'000)。在我们将所有体素重新定位到更接近零点(X:0、Y:0、Z:0)之后,所描述的问题就消失了。我们假设这与 XNA 使用的数据类型浮点数有关。根据 MSDN (http://msdn.microsoft.com/en-us/library/b1e65aza.aspx),浮点数的精度只有 7 位。我们得出的结论是,如果您将体素放在精度为 7 位的坐标上,并且因为 XNA 的 DepthBuffer 与浮点数一起使用,您将获得我们上面描述的效果。

也许有人可以证实我们的假设?

谢谢!

于 2012-10-03T14:08:24.790 回答