Monogame 我的 3D 对象重叠,而不是根据相对于相机的位置进行绘制

问题描述 投票:0回答:1

https://www.youtube.com/watch?v=QWImAT-g7tE

嘿,我在重叠 3D 对象时遇到了麻烦。我的 3D 渲染模型/对象是根据最后调用的绘制方法在彼此之上绘制的,而不是基于像素相对于相机的位置。深度缓冲应该可以自己解决这个问题..但事实并非如此

我被告知我的“深度读取”或“深度写入”失败了。我的“深度读取”是我假设将 DepthStencilState 设置为默认值:

            graphicsDevice.DepthStencilState = DepthStencilState.Default;
```cs

And the depth write is this right:
```cs
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

我已经尝试了一切。甚至删除 spritebatch,因为这会对缓冲和渲染产生一些影响。我剩下的唯一理论是我不断通过这行代码重置graphicsDevice Vertexbuffer

                graphicsDevice.SetVertexBuffer(shape.vertexBuffer);

但 ChatGPT 告诉我这不是问题。有谁知道我的问题可能出在哪里?以下是我绘制 3D 对象的方法:

    public override void Draw(GameTime gameTime, SpriteBatch spriteBatch) {
            graphicsDevice.DepthStencilState = DepthStencilState.Default;
            graphicsDevice.BlendState = BlendState.Opaque; // Spritebatch sets it default to AlphaBlend

            base.Draw(gameTime, spriteBatch);
            Draw3DModels();
            Draw3DShapes();
        }

        private void Draw3DModels() {
            foreach (ThreeDGameObject threeDGameObject in ThreeDObjects) {
                Model model = threeDGameObject.model;
                foreach (ModelMesh mesh in model.Meshes) {
                    foreach (BasicEffect effect in mesh.Effects) {

                        // Transformations
                        Matrix worldMatrix = Matrix.CreateTranslation(threeDGameObject.Position) *
                            Matrix.CreateFromYawPitchRoll(threeDGameObject.Rotation.Y, threeDGameObject.Rotation.X, threeDGameObject.Rotation.Z);
                        effect.World = worldMatrix;
                        effect.View = camera.View;
                        effect.Projection = camera.Projection;

                        // Light
                        // effect.AmbientLightColor = new Vector3(1f, 0, 0);
                        // effect.EnableDefaultLighting();

                        // Other shader settings
                        effect.TextureEnabled = true;
                        effect.Alpha = threeDGameObject.Alpha;

                        effect.CurrentTechnique.Passes[0].Apply();
                    }

                    mesh.Draw();
                }
            }
        }

        private void Draw3DShapes() {
            basicEffect.Projection = camera.Projection;
            basicEffect.View = camera.View;
            basicEffect.World = camera.World;

            // Draw all shapes
            foreach (Shape shape in shapes) { 
                // Transformations
                Matrix worldMatrix = Matrix.CreateTranslation(shape.Position) *
                    Matrix.CreateFromYawPitchRoll(shape.Rotation.Y, shape.Rotation.X, shape.Rotation.Z);
                basicEffect.World = worldMatrix;

                graphicsDevice.SetVertexBuffer(shape.vertexBuffer);
                graphicsDevice.Indices = shape.indexBuffer;

                foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { 
                    pass.Apply();
                    graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, shape.vertices.Length / 3);
                }
            }
        }

问题可能出在相机上吗?

我在 Visual Studio Code 中 单机游戏版本:3.8.1.303

3d monogame depth-buffer
1个回答
0
投票
GraphicsDevice.DepthStencilState = DepthStencilState.Default;

是启用深度缓冲区写入和读取的正确设置。

您还需要确保您的后缓冲区(主要目标帧缓冲区)应用了深度缓冲区。像这样,您在应用程序启动时设置 GraphicsDeviceManager 和后台缓冲区(继承的 Game 类的构造函数或其 Initialize() 函数):

DeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
DeviceManager.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;

深度缓冲区有多种可能的设置,但除“无”之外的任何设置都应该有效。

放置这条线也是个好主意

base.Draw(gameTime, spriteBatch);

在函数的末尾或开始时(例如,如果您只使用 SpriteBatch 绘制 UI,则更有可能在末尾)让我知道它是否有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.