【问题标题】:How to remove the effect of light / shadow on my model in XNA?如何在 XNA 中消除光/影对我的模型的影响?
【发布时间】:2013-02-26 21:08:55
【问题描述】:

我正在开发一个小游戏,我会绘制一个具有重复纹理的场地(土地)。我的问题是渲染结果。这给人的印象是我的立方体周围的一切看起来都像是一个光影。 是否可以在我的绘图功能中标准化灯光或去除阴影效果?

对不起我的英语不好..

这是一个屏幕截图,可以更好地理解我的问题。

这是我的代码绘制函数(带顶点缓冲区的实例化模型)

    // Draw Function (instancing model - vertexbuffer)
    public void DrawModelHardwareInstancing(Model model,Texture2D texture, Matrix[] modelBones,
                                     Matrix[] instances, Matrix view, Matrix projection)
    {
        if (instances.Length == 0)
            return;

        // If we have more instances than room in our vertex buffer, grow it to the neccessary size.
        if ((instanceVertexBuffer == null) ||
            (instances.Length > instanceVertexBuffer.VertexCount))
        {
            if (instanceVertexBuffer != null)
                instanceVertexBuffer.Dispose();

            instanceVertexBuffer = new DynamicVertexBuffer(Game.GraphicsDevice, instanceVertexDeclaration,
                                                           instances.Length, BufferUsage.WriteOnly);
        }

        // Transfer the latest instance transform matrices into the instanceVertexBuffer.
        instanceVertexBuffer.SetData(instances, 0, instances.Length, SetDataOptions.Discard);

        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (ModelMeshPart meshPart in mesh.MeshParts)
            {
                // Tell the GPU to read from both the model vertex buffer plus our instanceVertexBuffer.
                Game.GraphicsDevice.SetVertexBuffers(
                    new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
                    new VertexBufferBinding(instanceVertexBuffer, 0, 1)
                );

                Game.GraphicsDevice.Indices = meshPart.IndexBuffer;


                // Set up the instance rendering effect.
                Effect effect = meshPart.Effect;
                //effect.CurrentTechnique = effect.Techniques["HardwareInstancing"];
                effect.Parameters["World"].SetValue(modelBones[mesh.ParentBone.Index]);
                effect.Parameters["View"].SetValue(view);
                effect.Parameters["Projection"].SetValue(projection);
                effect.Parameters["Texture"].SetValue(texture);


                // Draw all the instance copies in a single call.
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    Game.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                           meshPart.NumVertices, meshPart.StartIndex,
                                                           meshPart.PrimitiveCount, instances.Length);
                }
            }



        }
    }
    // ### END FUNCTION DrawModelHardwareInstancing

【问题讨论】:

  • 你知道是光照问题还是纹理问题?
  • 你用什么程序来设计模型?
  • 我使用 Blender,是的,我是 sur,不是纹理问题
  • 默认情况下,Blender 中的法线不会被平均。我鼓励您使用法线来尝试修复模型。渲染视图是否显示平面或阴影面?如果渲染视图中的面是平面的,则问题可能出在导出上。

标签: graphics model 3d xna game-engine


【解决方案1】:

问题在于您使用的立方体网格。法线是平均的,但我猜你希望它们与立方体的面正交。

您将不得不使用总共 24 个顶点(每边 4 个)而不是 8 个顶点。每个角将有 3 个顶点,位置相同但法线不同,每个相邻面各有一个:

如果 FBX 导出器无法配置为正确导出法线,只需创建自己的立方体网格:

var vertices = new VertexPositionNormalTexture[24];

// Initialize the vertices, set position and texture coordinates
// ...

// Set normals

// front face
vertices[0].Normal = new Vector3(1, 0, 0);
vertices[1].Normal = new Vector3(1, 0, 0);
vertices[2].Normal = new Vector3(1, 0, 0);
vertices[3].Normal = new Vector3(1, 0, 0);

// back face
vertices[4].Normal = new Vector3(-1, 0, 0);
vertices[5].Normal = new Vector3(-1, 0, 0);
vertices[6].Normal = new Vector3(-1, 0, 0);
vertices[7].Normal = new Vector3(-1, 0, 0);

// ...

【讨论】:

    【解决方案2】:

    您的计算似乎不正确/没有法线。 Look at this example, specifically part 3.

    法线是一个向量,它描述了光在垂直照射时从该顶点/多边形反射的方向。

    I like this picture to demonstrate蓝线是曲线上每个特定点的法线方向。

    在 XNA 中,您可以计算具有顶点 vert1、vert2 和 vert3 的多边形的法线,如下所示:

    Vector3 dir = Vector3.Cross(vert2 - vert1, vert3 - vert1);
    Vector3 norm = Vector3.Normalize(dir);
    

    在很多情况下,这是由建模软件自动完成的,因此无需进行计算。如果您在代码中创建多维数据集,您可能确实需要执行该计算。

    【讨论】:

    • 啊,好吧!我使用 Blender 生成一个模型('fbx'),然后在我的 XNA 项目中加载这个模型。这意味着我可以在我的代码或 Blender 项目中更改灯光效果?
    • 可以试一试。对于搅拌机来说,这些都是一些非常奇怪的法线。有时,当它确实应该具有正交法线时,它会平均共享边的法线。尝试在搅拌机中选择整个立方体并点击 P。这将分离所有面,它应该为您提供更理智的法线。
    • 另一个想法,它可能会因为 FBX 导出器而这样做——但它会进行三角测量。如果上述方法不起作用,请尝试在搅拌机中对立方体进行三角剖分,在编辑模式下全选,然后(CTRL+T),然后拆分:(P)
    • 这会删除我的 UV 映射
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 2016-10-04
    • 2018-03-09
    • 2011-07-01
    • 1970-01-01
    • 2019-09-05
    相关资源
    最近更新 更多