这是一个老问题,但我昨天不得不自己解决这个问题,所以我想我会发布一个跟进:
如果您使用默认的 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
更改,.Normal
并且Vector4
尚未对其进行测试。可能需要将它们改回和。Vector3
float4
float3
Vector4
float4
当然,您需要一个采样器和像素着色器中的一些基本逻辑来读取每个纹理。Texture2D
假设您已经为包含颜色纹理和不透明度贴图的对象设置了两个效果参数 xTexture0 和 xTexture1 ,
// 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 中并且已经存储在 each MeshPart
'sVertexBuffer
中,因此您需要做的就是提取纹理,将其作为全局效果参数传递到着色器中,然后正常进行.