如果我绘制单个平面,则纹理坐标会正确映射。 (4 Verts,4 TC,6 Indices(2 polys))
即使它被细分,(9 Verts,9 TC,27 Indices(8 polys))纹理也会显示:
(玛雅复杂的飞机)
我可以使用我的[书面] Obj转换器并将纹理坐标加载到缓冲区中。但是,如果我在Maya中挤出一个面,甚至应用平面UV贴图来“修复”损坏的紫外线,(上图)纹理坐标在引擎中变得非常狂野。 (下面)
Obj纹理坐标格式是否存在问题?
更新:我使用D3D11_PRIMITIVE_TOPOLOGY_LINELIST绘制,并注意到索引也发生了变化.. 这会是问题吗?或者我应该在http://www.gamedev.net/topic/600234-texcoord-count-is-different-than-vertex-count/
刷新纹理坐标答案 0 :(得分:3)
此问题是由纹理坐标索引不等于顶点索引引起的。要解决此问题,必须对纹理坐标索引进行排序,以便与顶点索引对齐。
对于这个问题,我能够使用符合我理解的强力方法来解决这个问题,这个方法很慢,它将整个顶点/纹理坐标作为关键字编目,并重建完整的显式顶点数组和纹理坐标。索引,填充符合我的应用程序需求的自定义结构。
还有其他更快的解决方案涉及使用哈希 http://programminglinuxgames.blogspot.com/2010/03/wavefront-obj-file-format-opengl-vertex.html
法线的相关问题: OpenGL - Index buffers difficulties
一个很好的解释: Why is my OBJ parser rendering meshes like this?
关于obj格式的更多资源: http://en.wikipedia.org/wiki/Wavefront_.obj_file
OBJ资源: http://www.martinreddy.net/gfx/3d/OBJ.spec http://www.fileformat.info/format/wavefrontobj/egff.htm
此外,DirectX库中的MeshFromObj10教程可以帮助一些人,以有效的方式完成它。除了找到第三方来源之外,没有简单的方法来编码它。
答案 1 :(得分:2)
查看这些内容,它可能会对您有所帮助:
DirectX使用左侧的坐标系统。我想当你导出到.obj文件时,你将从Maya / 3ds Max获得一个右手坐标系 ://msdn.microsoft.com/en-us/library/windows/desktop/bb204853(V = vs.85)的.aspx
比较你的脊椎计数,在Maya中,然后在你的程序中。
找出你在TU / TV坐标中获得1.000671的原因,这看起来有点高。
确保导出为三角形而不是矩形。
在Maya中显示法线,看起来这个物体所在的地面/矩形的某些部分缺失。或者您可以尝试在D3D11_RASTERIZER_DESC中禁用剔除。
我现在没有在我的计算机上安装Maya,但我认为您可以在那里获得一个图形视图,向您显示纹理上的精确TU / TV坐标。
http://www.youtube.com/watch?v = T-fFpmBYP_Q该视频显示在4,21。
编辑:
提供一些代码示例:
struct D3D11TextureVertexType
{
XMFLOAT3 Position;
XMFLOAT2 TX;
};
这是你可以把顶点放在管道上的方法:
hr = m_pd3dImmediateContext->Map(MyID3D11Buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr)) return hr;
pData = (D3D11TextureVertexType*)mappedResource.pData;
memcpy(pData, MYOBJECTVERTICES/*this is D3D11TextureVertexType*/, sizeof(D3D11TextureVertexType) * VertexCount);
m_pd3dImmediateContext->Unmap(MyID3D11Buffer, 0);
stride = sizeof(D3D11TextureVertexType);
offset = 0;
m_pd3dImmediateContext->IASetVertexBuffers(0, 1, &MyID3D11Buffer, &stride, &offset);
m_pd3dImmediateContext->IASetIndexBuffer(m_AdjRectangleIBuffer, DXGI_FORMAT_R32_UINT, 0);
m_pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
result = m_TextureShader->Render(m_pd3dImmediateContext, 6, worldMatrix, viewMatrix, orthoMatrix, m_Textures[Q.textureID]->pSRV); if (!result)
{
return S_FALSE;
}
这是TextureShaderClass中的一些有趣的函数
bool Render(ID3D11DeviceContext* deviceContext, int indexCount, DirectX::CXMMATRIX worldMatrix, DirectX::CXMMATRIX viewMatrix, DirectX::CXMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture)
{
bool result;
result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture);
if (!result)
{
return false;
}
RenderShader(deviceContext, indexCount);
return true;
}
bool InitializeShader(ID3D11Device* device, const WCHAR* filename)
{
HRESULT result;
ID3D10Blob* errorMessage;
ID3D10Blob* vertexShaderBuffer;
ID3D10Blob* pixelShaderBuffer;
D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
unsigned int numElements;
D3D11_BUFFER_DESC matrixBufferDesc;
D3D11_SAMPLER_DESC samplerDesc;
errorMessage = 0;
vertexShaderBuffer = 0;
pixelShaderBuffer = 0;
result = D3DCompileFromFile(filename, NULL, NULL, "TextureVertexShader", "vs_5_0", 0, 0, &vertexShaderBuffer, &errorMessage);
if (FAILED(result))
{
if (errorMessage)
{
//OutputShaderErrorMessage(errorMessage, hwnd, filename);
}
else
{
MessageBox(0, filename, L"Missing Shader File", MB_OK);
}
return false;
}
result = D3DCompileFromFile(filename, NULL, NULL, "TexturePixelShader", "ps_5_0", 0, 0, &pixelShaderBuffer, &errorMessage);
if (FAILED(result))
{
if (errorMessage)
{
//OutputShaderErrorMessage(errorMessage, hwnd, psFilename);
}
else
{
MessageBox(0, filename, L"Missing Shader File", MB_OK);
}
return false;
}
result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader);
if (FAILED(result))
{
return false;
}
result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader);
if (FAILED(result))
{
return false;
}
polygonLayout[0].SemanticName = "POSITION";
polygonLayout[0].SemanticIndex = 0;
polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
polygonLayout[0].InputSlot = 0;
polygonLayout[0].AlignedByteOffset = 0;
polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[0].InstanceDataStepRate = 0;
polygonLayout[1].SemanticName = "TEXCOORD";
polygonLayout[1].SemanticIndex = 0;
polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
polygonLayout[1].InputSlot = 0;
polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
polygonLayout[1].InstanceDataStepRate = 0;
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_layout);
if (FAILED(result))
{
return false;
}
vertexShaderBuffer->Release();
vertexShaderBuffer = 0;
pixelShaderBuffer->Release();
pixelShaderBuffer = 0;
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
matrixBufferDesc.MiscFlags = 0;
matrixBufferDesc.StructureByteStride = 0;
result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
if (FAILED(result))
{
return false;
}
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.BorderColor[0] = 0;
samplerDesc.BorderColor[1] = 0;
samplerDesc.BorderColor[2] = 0;
samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = device->CreateSamplerState(&samplerDesc, &m_sampleState);
if (FAILED(result))
{
return false;
}
return true;
}
bool SetShaderParameters(ID3D11DeviceContext* deviceContext, DirectX::CXMMATRIX worldMatrix, DirectX::CXMMATRIX viewMatrix, DirectX::CXMMATRIX projectionMatrix, ID3D11ShaderResourceView* texture)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return false;
}
dataPtr = (MatrixBufferType*)mappedResource.pData;
DirectX::XMMATRIX world = worldMatrix;
world = XMMatrixTranspose(world);
DirectX::XMMATRIX view = viewMatrix;
view = XMMatrixTranspose(view);
DirectX::XMMATRIX projection = projectionMatrix;
projection = XMMatrixTranspose(projection);
dataPtr->world = world;
dataPtr->view = view;
dataPtr->projection = projection;
deviceContext->Unmap(m_matrixBuffer, 0);
bufferNumber = 0;
deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);
deviceContext->PSSetShaderResources(0, 1, &texture);
return true;
}
void RenderShader(ID3D11DeviceContext* deviceContext, int indexCount)
{
deviceContext->IASetInputLayout(m_layout);
deviceContext->VSSetShader(m_vertexShader, NULL, 0);
deviceContext->PSSetShader(m_pixelShader, NULL, 0);
deviceContext->PSSetSamplers(0, 1, &m_sampleState);
deviceContext->DrawIndexed(indexCount, 0, 0);
return;
}
答案 2 :(得分:1)
从Maya尝试在执行拉伸后重新导出纹理以进行正确的uv映射。
挤压创建新面孔,现有的uv贴图不适用于那些面孔。尝试使用Geometry清理工具。
据我所知,你在制作UV贴图后编辑模型,而不是将UV贴图更新为拉伸对象(仍然是计划者)。
您还可以尝试使用包含纹理的expert all选项,而不仅仅是.obj中的模型
Haven没有使用Maya一段时间:(