I have a c++/cx project where I want to render meshes (loaded from FBX-files) using DirectX-11. The FBX-files contain texture coordinates, but when rendering them, these UV-coordinates send to the vertexshader are completely wrong.
Here's how it looks:
These are supposed to be 2 human cyclists, but the texture is mapped completely wrong.
The vertexDescription is as follows:
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 },
};
Note that the Position and Nomal data are correct when rendering, it's only the texture coordinates that are wrong/missing.
VertexShader-input and -output:
struct VertexShaderInput
{
float3 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 color : COLOR0;
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
PixelShader-input:
struct PixelShaderInput
{
float4 color: COLOR0;
float2 uv : TEXCOORD0;
};
Here's a snippet of the fbx-file:
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,
//...
The fbx file is build into a cmo-file by visual studio, and it's loaded like this using directxtk:
_effectFactory = std::make_unique<EffectFactory>(_d3dDevice.Get());
_playerModel = Model::CreateFromCMO(_d3dDevice.Get(), L"Ambiorix.Track3DComponent\\PlayerModel.cmo", *_effectFactory);
The PlayerMesh is then initialized like this (_playerModel is passed to this function):
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.");
});
}
I can share more code, and the entire fbx file if it helps, just ask, I don't really know what else could be usefull to know.
If anyone can shed some light on how to get the uv coordinates correctly in the shaders, it would be most appreciated.
any help?
Edit: I initially stated the the UV's where 0, but I noticed that having
struct VertexShaderOutput
{
float4 color : COLOR0;
float2 uv : TEXCOORD;
float4 position : SV_POSITION;
};
instead of
struct VertexShaderOutput
{
float4 color : COLOR0;
float4 position : SV_POSITION;
float2 uv : TEXCOORD;
};
fixed that, no idea why though.