XNA .Fbx 纹理
我在 XNA 中使用标准 .fbx 导入器和自定义着色器。当我使用 BasicEffect 时,.fbx 模型经过正确的 UV 包裹并具有适当的纹理。但是,当我使用自定义效果时,我必须将纹理作为参数加载,并且它未正确映射。
问题: 1) 如何使用包含的纹理坐标和自定义效果正确地对我的 .fbx 模型进行纹理化? 2)有没有办法从加载的.fbx模型对象访问纹理?这个纹理去哪里了?
注意:我研究过自定义内容管道,并且不相信编写自己的 Fbx 导入器/处理器会很有效。但是,如果有人可以描述性地向我提供这就是答案的第一手经验,那么我将使用自定义管道。
感谢您花时间阅读这篇文章。
I'm using the standard .fbx importer with custom shaders in XNA. The .fbx model is UV wrapped properly and is textured appropriately when I use BasicEffect. However when I use my custom effect I have to load the texture in as a parameter, and it is not mapped correctly.
Questions: 1) How can I texture my .fbx model properly using the included texture's coordinates with custom effects? 2) Is there a way to access the texture from the loaded .fbx model object? Where does this texture go?
Note: I've studied custom content pipelines and don't believe writing my own Fbx importer/processor will be efficient. However if someone can descriptively supply me with firsthand experience of this being the answer than I will use the custom pipeline.
Thank you for your time and for reading this post.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个老问题,但我昨天必须自己解决这个问题,所以我想我应该发布后续内容:
如果您使用默认的 FBX 内容处理器并将
DefaultEffect
属性设置为 < code>BasicEffect,您可以通过以下方式获取对象的Texture2D
:请注意,模型中的每个网格可能具有不同的纹理。
纹理坐标与位置等一起存储在
MeshPart
的VertexBuffer
中。我看到了两个顶点声明。对于使用单个纹理(3DS Max 中的位图材质)的模型/网格,顶点声明为VertexPositionNormalTexture
。对于具有两个纹理(位图和不透明度/alpha 贴图)的模型,声明具有以下元素:
或者,包装到
IVertexType
结构中,以及等效的 HLSL 结构:
请注意,我更改了 < code>.Position 和
.Normal
从Vector4
和Vector3
到float4
和float3
在我发布此内容之前,尚未对其进行测试。它们可能需要改回Vector4
和float4
。当然,您需要一个采样器和像素着色器中的一些基本逻辑来读取每个纹理。假设您已将两个效果参数 xTexture0 和 xTexture1 设置为包含颜色纹理和不透明度贴图的
Texture2D
对象,这是一个简单的双纹理像素着色器。如果您只想要一个纹理,只需从第一个采样器读取并返回值,或者应用照明等。
这里的相关点是纹理坐标已经存在于 FBX 中,并且已经存储在每个
MeshPart< /code> 的
VertexBuffer
,因此您所需要做的就是提取纹理,将其作为全局效果参数传递到着色器中,然后照常进行。This is an old question, but I had to figure this out myself yesterday so I thought I'd post a followup:
If you're using the default FBX content processor and have the
DefaultEffect
property set toBasicEffect
, you can get theTexture2D
for the object via:Note that the each mesh in the model may have a different texture.
The texture coordinates are stored in the
MeshPart
'sVertexBuffer
along with position, etc. I've seen two vertex declarations. For a model/mesh that used a single texture (bitmap material in 3DS Max), the vertex declaration wasVertexPositionNormalTexture
.For a model that had two textures (a bitmap and an opacity/alpha map), the declaration had the elements:
or, wrapped into an
IVertexType
structure,and the equivelant HLSL structure:
Note that I changed
.Position
and.Normal
fromVector4
andVector3
tofloat4
andfloat3
before I posted this, and haven't tested it. It's possible that they may need to be changed back toVector4
andfloat4
.Of course, you'll need a sampler and some basic logic in your pixel shader to read each texture. Assuming you've set two effect parameters xTexture0 and xTexture1 to
Texture2D
objects containing your color texture and opacity map,and here's a simple two-texture pixel shader. If you only want one texture, just read from the first sampler and return the value, or apply lighting, etc.
The relevant points here are that the texture coordinates are already present in the FBX and are already stored in each
MeshPart
'sVertexBuffer
, so all you need to do is extract the texture, pass it into your shader as a global effect parameter, and proceed as normal.它不起作用的原因是您必须手动设置效果的参数,而不是依赖基本效果(它会在内容管道中设置着色器参数)。现在,我不熟悉你的着色器,所以我无法指定代码来解决你的问题......
要回答你的第二个问题,你可以以一种迂回的方式解决它。由于模型默认使用 basiceffect 加载到内容管道中,因此纹理将被导入并分配给管道内部的着色器参数。因此,如果您想访问它,您必须查看模型网格部件的默认效果属性。 这里是描述此过程的论坛帖子。
更正确的答案是在完全自定义导入器和仅使用默认导入器之间进行折衷。您可以创建一个继承现有模型处理器的自定义模型处理器。在那里,您可以导入自己的自定义效果,以及自定义纹理和需要设置的任何参数。并将其设置在模型内容上。有一篇文章(Shawn Hargreave 的博客或 msdn 上)展示了如何执行此操作,但遗憾的是我目前找不到它。
祝你好运!
The reason it's not working is because you have to set the effect's parameters manually instead of relying on the basiceffect (which would have had the shader parameters set in the content pipeline). Now, I'm not familiar with your shader so I couldn't prescribe code to solve your problem ...
To answer your second question, you can get around it in a roundabout sort of way. Because the model loads in the content pipeline with basiceffect by default, the texture is imported and assigned to the shader's parameters inside of the pipeline. So if you want to access it you'd have to look at the modelmeshpart's default effect property. Here is a forum post that describes this process.
The more correct answer would be a compromise between a full on custom importer and just using the default. You can make a custom modelprocessor that inherits from the existing one. In there, you can import your own custom effect, along with your custom textures and whatever parameters you need to set. and set it on the modelcontent. There was an article (either on Shawn Hargreave's blog, or on msdn) that showed how to do this, but I'm failing to find it at the moment unfortunately.
good luck!