【问题标题】:XNA multiples cubesXNA 倍数立方体
【发布时间】:2014-06-20 17:39:34
【问题描述】:

首先,请原谅我的英语,我是法国人... 我写了一个不起作用的代码。 我想画一个 mutliples 块,比如 Minecraft,但是在体素中。 在我地图的一侧,结果很好:

This render is opaque, good !

但另一方面,我明白了:

But in this side of my map, it's no good :(

有些面孔通过其他面孔出现... 谁有想法?我的法线?

我的函数 Remake() 没有被使用,它是用于删除面部...

    namespace LandOfCube.Models
{
    class Block
    {
        VertexBuffer instanceBuffer;
       public enum Form
        {
            all,
            noUp,
            noDown,
            noRight,
            noLeft,
            noFront,
            noBack
        }
       public Form cubeForm = Form.all;

        GraphicsDevice Graphics;
        Effect shader;
        private VertexBuffer vb;
        Color CubeColor;
        public Vector3 pos;

        VertexPositionColorNormal[] vertices;
        VertexPositionColorNormal[] verticesNoUp;
        VertexPositionColorNormal[] verticesNoDown;
        VertexPositionColorNormal[] verticesNoFront;
        VertexPositionColorNormal[] verticesNoBack;
        VertexPositionColorNormal[] verticesNoRight;
        VertexPositionColorNormal[] verticesNoLeft;


        private VertexPositionColorNormal[] Front = new VertexPositionColorNormal[5];
        private VertexPositionColorNormal[] Back = new VertexPositionColorNormal[5];
        private VertexPositionColorNormal[] Right = new VertexPositionColorNormal[5];
        private VertexPositionColorNormal[] Up = new VertexPositionColorNormal[5];
        private VertexPositionColorNormal[] Left = new VertexPositionColorNormal[5];
        private VertexPositionColorNormal[] Down = new VertexPositionColorNormal[5];

        public Vector3 normalFront = Vector3.Forward;
        public Vector3 normalBack = Vector3.Backward;
        public Vector3 normalTop = Vector3.Up;
        public Vector3 normalBottom = Vector3.Down;
        public Vector3 normalLeft = Vector3.Left;
        public Vector3 normalRight = Vector3.Right;

        public Block(GraphicsDevice graph, Color color, Vector3 position, ContentManager content)
        {


            Graphics = graph;

            shader = content.Load<Effect>("effects");
            CubeColor = color;
            pos = position;

            Init();
            SetVertices();

        }





        bool test = false;
        public void Draw(Camera camera)
        {



            Graphics.SetVertexBuffer(vb);

            shader.CurrentTechnique = shader.Techniques["Colored"];


            shader.Parameters["xView"].SetValue(camera.View);
            shader.Parameters["xProjection"].SetValue(camera.Projection);
            shader.Parameters["xWorld"].SetValue(Matrix.Identity);
            Vector3 lightDirection = new Vector3(1.0f, -1.0f, -1.0f);
            lightDirection.Normalize();
            shader.Parameters["xLightDirection"].SetValue(lightDirection);
            shader.Parameters["xAmbient"].SetValue(0.1f);
            shader.Parameters["xEnableLighting"].SetValue(true);


            foreach (EffectPass pass in shader.CurrentTechnique.Passes)
            {

                pass.Apply();
                this.Graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, vertices.Length / 3);
            }




        }








        #region Methode abstraites

        private void Init()
        {

            InitFront();
            InitBack();
            InitDown();
            InitUp();
            InitLeft();
            InitRight();
        }



        public void Remake()
        {
            switch (cubeForm)
            {
                case Form.noBack:
                    vertices = verticesNoBack;
                    break;
                case Form.noFront:
                    vertices = verticesNoFront;
                    break;
                case Form.noUp:
                    vertices = verticesNoUp;
                    break;
                case Form.noDown:
                    vertices = verticesNoDown;
                    break;
                case Form.noRight:
                    vertices = verticesNoRight;
                    break;
                case Form.noLeft:
                    vertices = verticesNoLeft;
                    break;
            }
            vb = new VertexBuffer(Graphics, typeof(VertexPositionColorNormal), vertices.Length, BufferUsage.None);
            vb.SetData(vertices);

            verticesNoBack = null;
            verticesNoDown = null;
            verticesNoFront = null;
            verticesNoLeft = null;
            verticesNoRight = null;
            verticesNoUp = null;

            test = true;
        }




        public void SetVertices()
        {
            this.vertices = new VertexPositionColorNormal[36];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }

            setNoBack();
            setNoFront();
            setNoUp();
            setNoDown();
            setNoRight();
            setNoLeft();

            vb = new VertexBuffer(Graphics, typeof(VertexPositionColorNormal), vertices.Length, BufferUsage.None);
            vb.SetData(vertices);
            Clean();
        }

        #region InitFaces

        public void setNoBack()
        {
            this.verticesNoBack = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }
        }
        public void setNoFront()
        {
            this.verticesNoFront = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }
        }
        public void setNoUp()
        {
            this.verticesNoUp = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }
        }
        public void setNoDown()
        {
            this.verticesNoFront = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }
        }
        public void setNoLeft()
        {
            this.verticesNoLeft = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Right[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }
        }
        public void setNoRight()
        {
            this.verticesNoRight = new VertexPositionColorNormal[30];
            int y = 0;
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Up[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Down[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Back[x]; y++;
            }

            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Front[x]; y++;
            }
            for (int x = 0; x < 6; x++)
            {
                this.vertices[y] = Left[x]; y++;
            }
        }


        public void InitFront()
        {
            this.Front = new VertexPositionColorNormal[6];

            Front[0].Position = new Vector3(pos.X, pos.Y + 1, pos.Z);
            Front[0].Color = Color.Blue;
            Front[0].Normal = normalFront;
            Front[1].Position = new Vector3(pos.X, pos.Y, pos.Z + 1);
            Front[1].Color = Color.Blue;
            Front[1].Normal = normalFront;
            Front[2].Position = new Vector3(pos.X, pos.Y, pos.Z);
            Front[2].Color = Color.Blue;
            Front[2].Normal = normalFront;


            Front[3].Position = new Vector3(pos.X, pos.Y + 1, pos.Z);
            Front[3].Color = Color.Blue;
            Front[3].Normal = normalFront;
            Front[4].Position = new Vector3(pos.X, pos.Y + 1, pos.Z + 1);
            Front[4].Color = Color.Blue;
            Front[4].Normal = normalFront;
            Front[5].Position = new Vector3(pos.X, pos.Y, pos.Z + 1);
            Front[5].Color = Color.Blue;
            Front[5].Normal = normalFront;
        }
        public void InitBack()
        {
            this.Back = new VertexPositionColorNormal[6];

            Back[0].Position = new Vector3(pos.X + 1, pos.Y, pos.Z + 1);
            Back[0].Color = Color.Red;
            Back[0].Normal = normalBack;
            Back[1].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Back[1].Color = Color.Red;
            Back[1].Normal = normalBack;
            Back[2].Position = new Vector3(pos.X + 1, pos.Y, pos.Z);
            Back[2].Color = Color.Red;
            Back[2].Normal = normalBack;


            Back[3].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z + 1);
            Back[3].Color = Color.Red;
            Back[3].Normal = normalBack;
            Back[4].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Back[4].Color = Color.Red;
            Back[4].Normal = normalBack;
            Back[5].Position = new Vector3(pos.X + 1, pos.Y, pos.Z + 1);
            Back[5].Color = Color.Red;
            Back[5].Normal = normalBack;
        }
        public void InitUp()
        {
            this.Up = new VertexPositionColorNormal[6];

            Up[0].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Up[0].Color = Color.Black;
            Up[0].Normal = normalTop;
            Up[1].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z + 1);
            Up[1].Color = Color.Black;
            Up[1].Normal = normalTop;
            Up[2].Position = new Vector3(pos.X, pos.Y + 1, pos.Z + 1);
            Up[2].Color = Color.Black;
            Up[2].Normal = normalTop;


            Up[3].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Up[3].Color = Color.Black;
            Up[3].Normal = normalTop;
            Up[4].Position = new Vector3(pos.X, pos.Y + 1, pos.Z + 1);
            Up[4].Color = Color.Black;
            Up[4].Normal = normalTop;
            Up[5].Position = new Vector3(pos.X, pos.Y + 1, pos.Z);
            Up[5].Color = Color.Black;
            Up[5].Normal = normalTop;
        }
        public void InitDown()
        {
            this.Down = new VertexPositionColorNormal[6];

            Down[0].Position = new Vector3(pos.X + 1, pos.Y, pos.Z);
            Down[0].Color = Color.Orange;
            Down[0].Normal = normalBottom;
            Down[1].Position = new Vector3(pos.X, pos.Y, pos.Z);
            Down[1].Color = Color.Orange;
            Down[1].Normal = normalBottom;
            Down[2].Position = new Vector3(pos.X, pos.Y, pos.Z + 1);
            Down[2].Color = Color.Orange;
            Down[2].Normal = normalBottom;


            Down[3].Position = new Vector3(pos.X + 1, pos.Y, pos.Z);
            Down[3].Color = Color.Orange;
            Down[3].Normal = normalBottom;
            Down[4].Position = new Vector3(pos.X, pos.Y, pos.Z + 1);
            Down[4].Color = Color.Orange;
            Down[4].Normal = normalBottom;
            Down[5].Position = new Vector3(pos.X + 1, pos.Y, pos.Z + 1);
            Down[5].Color = Color.Orange;
            Down[5].Normal = normalBottom;
        }
        public void InitRight()
        {
            this.Right = new VertexPositionColorNormal[6];

            Right[0].Position = new Vector3(pos.X + 1, pos.Y, pos.Z + 1);
            Right[0].Color = Color.Green;
            Right[0].Normal = normalRight;
            Right[1].Position = new Vector3(pos.X, pos.Y, pos.Z + 1);
            Right[1].Color = Color.Green;
            Right[1].Normal = normalRight;
            Right[2].Position = new Vector3(pos.X, pos.Y + 1, pos.Z + 1);
            Right[2].Color = Color.Green;
            Right[3].Normal = normalRight;


            Right[3].Position = new Vector3(pos.X + 1, pos.Y, pos.Z + 1);
            Right[3].Color = Color.Green;
            Right[3].Normal = normalRight;
            Right[4].Position = new Vector3(pos.X, pos.Y + 1, pos.Z + 1);
            Right[4].Color = Color.Green;
            Right[4].Normal = normalRight;
            Right[5].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z + 1);
            Right[5].Color = Color.Green;
            Right[5].Normal = normalRight;
        }
        public void InitLeft()
        {
            this.Left = new VertexPositionColorNormal[6];

            Left[0].Position = new Vector3(pos.X, pos.Y, pos.Z);
            Left[0].Color = Color.Aqua;
            Left[0].Normal = normalLeft;
            Left[1].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Left[1].Color = Color.Aqua;
            Left[1].Normal = normalLeft;
            Left[2].Position = new Vector3(pos.X, pos.Y + 1, pos.Z);
            Left[2].Color = Color.Aqua;
            Left[2].Normal = normalLeft;


            Left[3].Position = new Vector3(pos.X, pos.Y, pos.Z);
            Left[3].Color = Color.Aqua;
            Left[3].Normal = normalLeft;
            Left[4].Position = new Vector3(pos.X + 1, pos.Y, pos.Z);
            Left[4].Color = Color.Aqua;
            Left[4].Normal = normalLeft;
            Left[5].Position = new Vector3(pos.X + 1, pos.Y + 1, pos.Z);
            Left[5].Color = Color.Aqua;
            Left[5].Normal = normalLeft;
        }

        #endregion
        private void setTriangleNormal(VertexPositionColorNormal v1, VertexPositionColorNormal v2, VertexPositionColorNormal v3)
        {

            Vector3 side1 = v1.Position - v3.Position;
            Vector3 side2 = v1.Position - v2.Position;
            Vector3 normal = Vector3.Cross(side1, side2);

            v1.Normal += normal;
            v2.Normal += normal;
            v3.Normal += normal;

            v1.Position.Normalize();
            v1.Position.Normalize();
            v1.Position.Normalize();
        }



        public void Clean()
        {
            Front = null;
            Back = null;
            Right = null;
            Left = null;
            Up = null;
            Down = null;

        }
        #endregion

    }
}

【问题讨论】:

  • 是的,我们当然需要代码。
  • 我怀疑深度缓冲区或状态无效。您是否篡改了这些设置?
  • 不,我没有碰过这个设置:/

标签: c# xna voxel


【解决方案1】:

我的猜测是您将立方体背面的顶点以错误的方向缠绕,使它们的法线指向立方体的内部而不是外部。 3D 代码中一种非常常见的优化是只绘制法线朝向相机的三角形。

【讨论】:

  • 这不是常见的优化。事实上,我不知道有任何引擎可以做到这一点。您可能是指背面剔除。但是,法线与背面剔除无关。决定一个面是否被剔除的是所有顶点的缠绕顺序。无论如何,正如您在代码中看到的那样,情况并非如此。
  • 背面剔除正是我所指的。它与表面法线直接相关。任何具有远离相机的法线指向的表面都将被丢弃。缠绕顺序错误会翻转法线并导致表面被剔除。
  • 请注意措辞。法线是顶点的属性。通常,这些属性是跨面插值的。此属性不参与背面剔除。我们可以为面引入另一个法线,它只取决于顶点的位置。我们可以根据这个值定义剔除。然而,这是模棱两可的,因此不常用。因此,我们只说缠绕顺序。不是另一张脸正常。
  • 我想你可能想在这里仔细检查一下自己。法线是平面的属性,而不是顶点。顶点是 3D 空间中的一个简单位置,仅此而已。由 3 个顶点定义的平面具有normal;其方向由缠绕顺序定义。每个顶点的法线实际上是通过从其相邻平面的中心进行插值来计算的。 en.wikipedia.org/wiki/Surface_normalen.wikipedia.org/wiki/Back-face_culling
  • 我不是这个意思。当您指定几何图形时,您将多个属性分配给顶点 - 位置、颜色、纹理坐标、法线(顶点不仅是一个位置,而且是图中的一个节点)。此法线在光栅化阶段跨面内插以用于照明。剔除发生在光栅化之前。是的,剔除可以说是使用表面法线(与插值顶点法线不同)。但正如我所说,这很快就会导致混淆,所以我不建议使用这个定义。
猜你喜欢
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多