我有一个 c++/cx 项目,我想使用 DirectX-11 渲染网格(从 FBX 文件加载)。FBX 文件包含纹理坐标,但是在渲染它们时,这些发送到顶点着色器的 UV 坐标是完全错误的。
这是它的外观:
这些应该是 2 名骑自行车的人,但纹理映射完全错误。
顶点描述如下:
D3D11_INPUT_ELEMENT_DESC _vertexDescriptions[3] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
请注意,Position 和 Nomal 数据在渲染时是正确的,只有纹理坐标是错误/缺失的。
VertexShader-输入和-输出:
struct VertexShaderInput
{
float3 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 color : COLOR0;
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
像素着色器输入:
struct PixelShaderInput
{
float4 color: COLOR0;
float2 uv : TEXCOORD0;
};
这是 fbx 文件的片段:
LayerElementUV: 0 {
Version: 101
Name: "UVTex"
MappingInformationType: "ByPolygonVertex"
ReferenceInformationType: "IndexToDirect"
UV: 0.118273,0.459037,0.598600,0.180400,0.647187,0.129884,
//...
UVIndex: 2136,255,879,734,2136,734,3602,1034,1034,3602,6071,1176,
//...
fbx 文件由 Visual Studio 构建为 cmo 文件,并使用 directxtk 像这样加载:
_effectFactory = std::make_unique<EffectFactory>(_d3dDevice.Get());
_playerModel = Model::CreateFromCMO(_d3dDevice.Get(), L"Ambiorix.Track3DComponent\\PlayerModel.cmo", *_effectFactory);
然后像这样初始化 PlayerMesh(_playerModel 被传递给这个函数):
task<void> PlayerMesh::InitializeAsync(Model *const model)
{
_logger->Trace(L"PlayerMesh.InitializeAsync()");
_isInitialized = false;
_primitiveTopology = model->meshes[0]->meshParts[0]->primitiveType;
_vertexBufferStride = model->meshes[0]->meshParts[0]->vertexStride;
_vertexBufferOffset = model->meshes[0]->meshParts[0]->vertexOffset;
_vertexBuffer = model->meshes[0]->meshParts[0]->vertexBuffer;
_inputLayout = model->meshes[0]->meshParts[0]->inputLayout;
_indexFormat = model->meshes[0]->meshParts[0]->indexFormat;
_indexCount = model->meshes[0]->meshParts[0]->indexCount;
_indexBuffer = model->meshes[0]->meshParts[0]->indexBuffer;
std::vector<task<void>> tasks;
tasks.push_back(CreateVertexShaderAsync(_vertexShaderRelativeFilePath, _vertexDescriptions, ARRAYSIZE(_vertexDescriptions)));
tasks.push_back(CreatePixelShaderAsync(_pixelShaderRelativeFilePath));
return when_all(tasks.begin(), tasks.end())
.then([this]
{
CreateSamplerState();
auto createTextureResult = CreateDDSTextureFromFile(_d3dDevice.Get(), _textureRelativeFilePath->Data(), nullptr, _texture.ReleaseAndGetAddressOf());
if (FAILED(createTextureResult))
{
_logger->Error(L"Failed to create texture.");
return;
}
PlayerMeshConstantBuffer solidColorConstantBuffer;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = &solidColorConstantBuffer;
InitData.SysMemPitch = 0u;
InitData.SysMemSlicePitch = 0u;
CD3D11_BUFFER_DESC bufferDescription(sizeof(PlayerMeshConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
auto createConstantBuffer = _d3dDevice->CreateBuffer(&bufferDescription, &InitData, _constantBuffer.GetAddressOf());
if (FAILED(createConstantBuffer))
{
_logger->Error(L"PlayerMesh.InitializeAsync() | Failed to create constant buffer.");
return;
}
_isInitialized = true;
_logger->Trace("PlayerMesh.InitializeAsync() | Done.");
});
}
如果有帮助,我可以分享更多代码和整个 fbx 文件,请问,我真的不知道还有什么有用的信息。
如果有人可以阐明如何在着色器中正确获取 uv 坐标,将不胜感激。
有什么帮助吗?
编辑:我最初说 UV 的位置为 0,但我注意到有
struct VertexShaderOutput
{
float4 color : COLOR0;
float2 uv : TEXCOORD;
float4 position : SV_POSITION;
};
代替
struct VertexShaderOutput
{
float4 color : COLOR0;
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};
解决了这个问题,但不知道为什么。