gpt4 book ai didi

XNA .Fbx 纹理

转载 作者:行者123 更新时间:2023-12-01 10:15:01 31 4
gpt4 key购买 nike

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

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

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

感谢您抽空阅读这篇文章。

最佳答案

这是一个老问题,但我昨天不得不自己解决这个问题,所以我想我会发布一个后续问题:

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

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

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

纹理坐标与位置等一起存储在MeshPartVertexBuffer 中。我看到了两个顶点声明。对于使用单个纹理(3DS Max 中的位图 Material )的模型/网格,顶点声明为 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 中,因此您需要做的就是提取纹理,将其作为全局效果参数传递到着色器中,然后照常进行。

关于XNA .Fbx 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1765779/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com