如何从 Blender 中导出 fbx 纹理以在 Monogame 中使用

Posted

技术标签:

【中文标题】如何从 Blender 中导出 fbx 纹理以在 Monogame 中使用【英文标题】:How to export fbx textures from Blender for use in Monogame 【发布时间】:2019-09-16 19:15:58 【问题描述】:

我正在尝试使用 Blender 制作一张简单的扑克牌,正面和背面的两侧都有纹理,并将其加载到 Monogame。模型本身很好,运行时会在模拟器上显示,但我似乎无法获得包含的纹理。

卡片上的纹理在 Blender 中似乎可以正常渲染。材质设置为“无阴影”,因此它们不应该受到光照水平的影响,对吗?

导出文件时,我尝试使用不同的版本设置和从“复制”到“条带路径”的各种不同路径模式。

内容管理器将输出目录设置为主内容文件夹,因此我希望纹理不存在引用问题。

所有纹理本身都在同一个文件夹中。

内容全部手动加载到 Visual Studio 中。

这是我用来绘制卡片的代码,显示了我玩过的不同灯光设置。

    private void DrawCard(Model m, Vector3 v, CardFacing c, PlayerFacing p)
    
        foreach (var mesh in m.Meshes)
        
            foreach (var effect1 in mesh.Effects)
            
                var effect = (BasicEffect)effect1;

                effect.TextureEnabled = true;
                effect.EnableDefaultLighting();
                //effect.PreferPerPixelLighting = true;

                //effect.AmbientLightColor = Color.White.ToVector3();
                effect.DiffuseColor = Color.White.ToVector3();
                //effect.EmissiveColor = Color.White.ToVector3() * 2f;

                //effect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(0, 0, 1));

                effect.Alpha = 1;
                effect.VertexColorEnabled = false;

                Matrix mCardFacing = new Matrix();

                switch(c)
                
                    case CardFacing.Down:
                        mCardFacing = Matrix.CreateRotationY((float)(Math.PI / 180) * 180) * Matrix.CreateRotationX((float)(Math.PI / 180) * 90) * Matrix.CreateTranslation(new Vector3(0, 0, 0));
                        break;
                    case CardFacing.Up:
                        mCardFacing = Matrix.CreateRotationZ((float)(Math.PI / 180) * 180) * Matrix.CreateRotationX((float)(Math.PI / 180) * 90) * Matrix.CreateTranslation(new Vector3(0, 0, 0));
                        break;
                    case CardFacing.Hand:
                        mCardFacing = Matrix.CreateRotationX((float)(Math.PI / 180) * -20);
                        break;
                

                Matrix mPlayerFacing = new Matrix();

                switch (p)
                
                    case PlayerFacing.North:
                        mPlayerFacing = Matrix.CreateRotationZ((float)(Math.PI / 180) * 0);
                        break;
                    case PlayerFacing.East:
                        mPlayerFacing = Matrix.CreateRotationZ((float)(Math.PI / 180) * 90);
                        break;
                    case PlayerFacing.South:
                        mPlayerFacing = Matrix.CreateRotationZ((float)(Math.PI / 180) * 180);
                        break;
                    case PlayerFacing.West:
                        mPlayerFacing = Matrix.CreateRotationZ((float)(Math.PI / 180) * 270);
                        break;
                

                effect.World = mCardFacing * Matrix.CreateTranslation(v) * mPlayerFacing;
                effect.View = view;
                effect.Projection = projection;
            

            mesh.Draw();
        
    

有什么想法吗?谢谢。

【问题讨论】:

“材质设置为 'shadeless' 所以它们不应该受到光照水平的影响,对吗?”,目标/效果支持导出定义的材质:答案是否定的。没有通过.fbx 提供的“照明信息”将灯(或缺少灯)关联为发射通道。 【参考方案1】:

3d 模型通常不包含纹理本身。 FBX 文件存储每个顶点的位置、它们的连接方式以及纹理的哪一部分位于任意单个点。

它不存储纹理本身。因此,您需要像加载任何其他纹理一样单独加载纹理(您需要一个 Texture2D,即使这是一个 3d 模型)。

然后,您可以将纹理分配给效果:

effect.Texture = cardTexture;

我相信这应该可以正确渲染效果。

这意味着您还可以轻松地动态更换模型的纹理,而无需更改模型本身。如果您的模型只是一个二维四边形,那么在代码中生成它也可能更简单,但您当前的设置也没有错。

【讨论】:

感谢您的回复。我认为使用管道工具创建的两个文件是对纹理的引用?我假设文件 S_J_0.xnb 和 Z_Back_0.xnb 是为纹理创建的,因为这些文件被称为 S_J.jpg 和 Z_Back.jpg 此外,我曾在某一时刻工作过的代码。我第一次做了图像中的内容。然后编辑卡片的大小并丢失纹理。 !Cards with textures 很奇怪,你让它在某个时候工作,但也许我记错了什么......据我所知,FBX 格式不包含任何纹理,所以 Monogame 应该不能自动访问纹理。你试过手动设置 effect.Texture 吗? 据我了解,您是对的,fbx 只是一个文本文档。内容管道工具在构建 fbx 文件时会将所有图像捆绑到 xnb 文件中,并且脚本会引用它。这是我开始的原始示例。其中的机器人模型不会在运行时绘制机器人的纹理,它们是模型的一部分。在绘制顶点时手动设置纹理是我用于地板和桌子的方法。 docs.microsoft.com/en-us/xamarin/graphics-games/monogame/3d/… FBX 文件可以包含简单的材质定义和对纹理文件的引用。 blender FBX exporter 和 FBX(Model) Content importers 是否支持这个,我不知道。 @Strom 你好。我已经用 Notepad++ 打开了 fbx 文件和 xnb,它们看起来是正确的。 fbx 引用主 xnb 文件 (S_J),然后引用其他两个 xnb 文件(S_J_0 和 Z_Back)中的两个纹理。 i.imgur.com/kOJ3d8r.png【参考方案2】:

您可能忘记在 .FBX 中包含嵌入式资源。请将您的导出设置 Path Mode 更改为 Copy 并启用它旁边的按钮。参考本教程:https://www.youtube.com/watch?v=kEP34CbPWUo

编辑:

这对我不起作用,因为 Monogame 内容构建工具总是无法构建内容并出现错误:

*/Content/Wall2.fbx: error: The source file '*/Content/*0' does not exist!

然后我只是导出了没有嵌入纹理的 .FBX,而是手动将纹理图片添加到 Content.mgcb 并将 TextureFormat 切换为 'NoChange' 效果很好!

附:我建议将此问题移至https://gamedev.stackexchange.com/

【讨论】:

以上是关于如何从 Blender 中导出 fbx 纹理以在 Monogame 中使用的主要内容,如果未能解决你的问题,请参考以下文章

如何从Blender导出fbx纹理以用于Monogame

将 .FBX 从 Blender 导入 Unity 时出现深色纹理

在 Blender 中导入 .fbx 字符[关闭]

为啥从 Blender 导出到 Unity (.fbx) 后动画会这样 [关闭]

如何在搅拌机中导入 FBX?

如何在 Blender 导出脚本中导出每个顶点的 UV 坐标