【问题标题】:XNA .Fbx texturesXNA .Fbx 纹理
【发布时间】:2010-12-18 10:58:01
【问题描述】:

我在 XNA 中使用带有自定义着色器的标准 .fbx 导入器。当我使用 BasicEffect 时,.fbx 模型已正确包裹 UV 并且具有适当的纹理。但是,当我使用自定义效果时,我必须将纹理作为参数加载,并且它没有正确映射。

问题:1) 如何使用包含的纹理坐标和自定义效果正确地纹理我的 .fbx 模型? 2) 有没有办法从加载的 .fbx 模型对象中访问纹理?这个纹理去哪里了?

注意:我研究过自定义内容管道,不相信编写自己的 Fbx 导入器/处理器会很有效。但是,如果有人可以描述性地向我提供作为答案的第一手经验,那么我将使用自定义管道。

感谢您抽出宝贵时间阅读这篇文章。

【问题讨论】:

    标签: xna textures shader


    【解决方案1】:

    它不起作用的原因是您必须手动设置效果的参数,而不是依赖基本效果(这将在内容管道中设置着色器参数)。现在,我不熟悉你的着色器,所以我无法指定代码来解决你的问题......

    要回答您的第二个问题,您可以绕道而行。因为模型默认加载到内容管线中的基本效果,所以纹理被导入并分配给管线inside的着色器参数。因此,如果您想访问它,您必须查看模型网格部分的默认效果属性。 Here 是描述此过程的论坛帖子。

    更正确的答案是在完全自定义导入器和仅使用默认导入器之间进行折衷。您可以制作一个继承自现有模型处理器的自定义模型处理器。在那里,您可以导入您自己的自定义效果,以及您的自定义纹理和您需要设置的任何参数。并将其设置在模型内容上。有一篇文章(在 Shawn Hargreave 的博客或 msdn 上)展示了如何执行此操作,但不幸的是我现在找不到它。

    祝你好运!

    【讨论】:

    • 这是在 FBX 文件中重现 3DS max 效果的过程吗?
    • (以防万一有人遇到并需要它)GS 3.1 的蒙皮效果示例(在他们引入库存 SkinnedEffect 之前)[create.msdn.com/en-US/education/catalog/sample/skinned_model] 展示了如何将 BasicEffect 换成加载的自定义着色器设计时间。 (ConvertMaterial 方法)
    【解决方案2】:

    这是一个老问题,但我昨天必须自己解决这个问题,所以我想我会发布一个跟进:

    如果您使用默认的 FBX 内容处理器并将DefaultEffect 属性设置为BasicEffect,您可以通过以下方式获取对象的Texture2D

    texture = ((BasicEffect)model.Meshes[0].Effects[0]).Texture;
    

    请注意,模型中的每个网格可能具有不同的纹理。

    纹理坐标与位置等一起存储在MeshPart'sVertexBuffer 中。我见过两个顶点声明。对于使用单个纹理(3DS Max 中的位图材质)的模型/网格,顶点声明为 VertexPositionNormalTexture

    对于具有两个纹理(一个位图和一个不透明度/alpha 映射)的模型,声明包含以下元素:

    Position
    Normal
    Texture (usage index 0)
    Texture (usage index 1)
    

    或者,包裹在IVertexType结构中,

    public struct VertexPositionNormalTextureTexture : IVertexType
    {
        public Vector3 Position;
        public Vector3 Normal;
        public Vector4 Texture0;
        public Vector4 Texture1;
    
        public static VertexDeclaration VertexDeclaration
        {
            get
            {
                return new VertexDeclaration
                (
                new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
                ,
                new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
                ,
                new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 0)
                ,
                new VertexElement(0,VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 1)
                );
            }
        }
    
    
        VertexDeclaration IVertexType.VertexDeclaration
        {
            get { return VertexDeclaration; }
        }
    }
    

    以及等效的 HLSL 结构:

    struct VertexPositionNormalTextureTexture
    {
        float3 Position : POSITION0;
        float3 Normal : NORMAL0;
        float4 Texture0 : TEXCOORD0;
        float4 Texture1 : TEXCOORD1;
    };
    

    请注意,在发布此内容之前,我已将 .Position.NormalVector4Vector3 更改为 float4float3,并且尚未对其进行测试。可能需要将它们改回Vector4float4

    当然,您需要一个采样器和像素着色器中的一些基本逻辑来读取每个纹理。假设您已将两个效果参数 xTexture0 和 xTexture1 设置为 Texture2D 包含颜色纹理和不透明度贴图的对象,

    // texture sampler
    sampler Sampler0 = sampler_state
    {
        Texture = (xTexture0);
    };
    
    sampler Sampler1 = sampler_state
    {
        Texture = (xTexture1);
    };
    

    这是一个简单的两纹理像素着色器。如果您只想要一个纹理,只需从第一个采样器中读取并返回值,或应用光照等。

    float4 TwoTexturePixelShader(VertexPositionNormalTextureTexture input) : COLOR0
    {
        float4 texel0;
        float4 texel1;
        float4 pixel;
    
        // check global effect parameter to see if we want textures turned on
        // (useful for debugging geometry weirdness)
        if (TexturesEnabled)
        {
            texel0 = tex2D(Sampler0, input.Texture0);
            texel1 = tex2D(Sampler1, input.Texture1);       
            /// Assume texel1 is an alpha map, so just multiple texel0 by that alpha.
            pixel.rgb=texel0.rgb;
            pixel.a=texel0.a;
        }
        else
            /// return 100% green
            pixel = float4(0,1,0,1);
    
        return pixel;
    
    } 
    

    这里的相关点是纹理坐标已经存在于FBX中并且已经存储在每个MeshPartVertexBuffer中,所以你需要做的就是提取纹理,将它传递给你的着色器一个全局效果参数,然后照常进行。

    【讨论】:

      猜你喜欢
      • 2013-02-05
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-07
      • 2015-12-01
      • 2014-08-31
      • 1970-01-01
      相关资源
      最近更新 更多