DirectX11 每个三角形使用缓冲区中的第一个顶点
DirectX11 each triangle using first vertex in the buffer
我目前的 DirectX 11 体素渲染器出现问题,每当渲染三角形时,都会使用缓冲区中的第一个顶点,而不是正确的顶点之一。
我在 Unity 中有一个相同网格生成算法的工作版本,比较索引和顶点后,它们完全相同,所以我不认为问题出在算法上。
我知道正在使用缓冲区中的第一个顶点的原因是因为为每个块创建的第一个顶点位于块的原点。每个块GameObject的世界位置是(0, 0, 0),块的位置只是在构建每个块的网格时作为每个顶点的偏移量添加。
正如您在下图中看到的,三角形正在拉伸到块的原点(第一个顶点)。仍然可以看到体素地形的山地形状,因此一些顶点被渲染在正确的位置。我只是不明白为什么似乎每三个索引都设置为 0(我不确定这是否真的发生了,它看起来就像我想象的那样)。
这是我用来为每个块创建顶点和索引缓冲区的代码。 m_vertices 和 m_indices 都是向量,当我比较它们时,它们与工作的 Unity 版本相同。
VoxelMesh mesh;
DirectX::VertexPositionNormalTexture* verticesArray = new DirectX::VertexPositionNormalTexture[m_vertices.size()];
for (unsigned int i = 0; i < m_vertices.size(); i++) {
verticesArray[i].position = m_vertices[i];
verticesArray[i].normal = m_normals[i];
verticesArray[i].textureCoordinate = m_uvs[i];
}
//Create vertex buffer
ID3D11Buffer* vertexBuffer;
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(DirectX::VertexPositionNormalTexture) * m_vertices.size();
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = verticesArray;
device->CreateBuffer(&bd, &InitData, &vertexBuffer);
mesh.m_VertexBuffer = vertexBuffer;
mesh.m_VBOffset = 0;
mesh.m_VBStride = sizeof(DirectX::VertexPositionNormalTexture);
//Create index buffer
unsigned int* indicesArray = new unsigned int[m_indices.size()];
for (unsigned int i = 0; i < m_indices.size(); i++) {
indicesArray[i] = m_indices[i];
}
ID3D11Buffer* indexBuffer;
D3D11_BUFFER_DESC bd1;
ZeroMemory(&bd1, sizeof(bd1));
bd1.Usage = D3D11_USAGE_DEFAULT;
bd1.ByteWidth = sizeof(WORD) * m_indices.size();
bd1.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd1.CPUAccessFlags = 0;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = indicesArray;
device->CreateBuffer(&bd1, &InitData, &indexBuffer);
mesh.m_IndexCount = m_indices.size();
mesh.m_IndexBuffer = indexBuffer;
delete[] indicesArray;
delete[] verticesArray;
体素网格结构:
struct VoxelMesh {
ID3D11Buffer* m_VertexBuffer;
ID3D11Buffer* m_IndexBuffer;
UINT m_VBStride;
UINT m_VBOffset;
UINT m_IndexCount;
};
您的索引缓冲区声明为 R16_UINT,但您提供的缓冲区使用的是 32 位索引。将 indicesArray
更改为 unsigned short*
,或者将缓冲区更改为 R32_UINT.
我目前的 DirectX 11 体素渲染器出现问题,每当渲染三角形时,都会使用缓冲区中的第一个顶点,而不是正确的顶点之一。
我在 Unity 中有一个相同网格生成算法的工作版本,比较索引和顶点后,它们完全相同,所以我不认为问题出在算法上。
我知道正在使用缓冲区中的第一个顶点的原因是因为为每个块创建的第一个顶点位于块的原点。每个块GameObject的世界位置是(0, 0, 0),块的位置只是在构建每个块的网格时作为每个顶点的偏移量添加。
正如您在下图中看到的,三角形正在拉伸到块的原点(第一个顶点)。仍然可以看到体素地形的山地形状,因此一些顶点被渲染在正确的位置。我只是不明白为什么似乎每三个索引都设置为 0(我不确定这是否真的发生了,它看起来就像我想象的那样)。
这是我用来为每个块创建顶点和索引缓冲区的代码。 m_vertices 和 m_indices 都是向量,当我比较它们时,它们与工作的 Unity 版本相同。
VoxelMesh mesh;
DirectX::VertexPositionNormalTexture* verticesArray = new DirectX::VertexPositionNormalTexture[m_vertices.size()];
for (unsigned int i = 0; i < m_vertices.size(); i++) {
verticesArray[i].position = m_vertices[i];
verticesArray[i].normal = m_normals[i];
verticesArray[i].textureCoordinate = m_uvs[i];
}
//Create vertex buffer
ID3D11Buffer* vertexBuffer;
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(DirectX::VertexPositionNormalTexture) * m_vertices.size();
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = verticesArray;
device->CreateBuffer(&bd, &InitData, &vertexBuffer);
mesh.m_VertexBuffer = vertexBuffer;
mesh.m_VBOffset = 0;
mesh.m_VBStride = sizeof(DirectX::VertexPositionNormalTexture);
//Create index buffer
unsigned int* indicesArray = new unsigned int[m_indices.size()];
for (unsigned int i = 0; i < m_indices.size(); i++) {
indicesArray[i] = m_indices[i];
}
ID3D11Buffer* indexBuffer;
D3D11_BUFFER_DESC bd1;
ZeroMemory(&bd1, sizeof(bd1));
bd1.Usage = D3D11_USAGE_DEFAULT;
bd1.ByteWidth = sizeof(WORD) * m_indices.size();
bd1.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd1.CPUAccessFlags = 0;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = indicesArray;
device->CreateBuffer(&bd1, &InitData, &indexBuffer);
mesh.m_IndexCount = m_indices.size();
mesh.m_IndexBuffer = indexBuffer;
delete[] indicesArray;
delete[] verticesArray;
体素网格结构:
struct VoxelMesh {
ID3D11Buffer* m_VertexBuffer;
ID3D11Buffer* m_IndexBuffer;
UINT m_VBStride;
UINT m_VBOffset;
UINT m_IndexCount;
};
您的索引缓冲区声明为 R16_UINT,但您提供的缓冲区使用的是 32 位索引。将 indicesArray
更改为 unsigned short*
,或者将缓冲区更改为 R32_UINT.