Vulkan线网格创建中X、Y方向末位线条缺失问题的排查与修复
I recently implemented a 3D line grid following the method from 3D Game Programming with DirectX 12, but when running my Vulkan application, the final lines along the X and Y axes were missing. Initially, I suspected issues with VK_POLYGON_MODE_LINE or VK_PRIMITIVE_TOPOLOGY_LINE_LIST, but after verifying both settings worked correctly, I found the problem lay in how I constructed the index buffer.
Original Problematic Code
Here's the initial grid creation code that caused the missing lines:
struct Vertex { glm::vec3 position; glm::vec3 color; }; Mesh Mesh::CreateGrid(DrawingInstance& instance, float width, float depth, unsigned int m, unsigned int n) { // 3D Game Programming with DirectX 12 - P. 302ff std::vector<Vertex> vertices; std::vector<uint32_t> indices; unsigned int vertexCount = m * n; unsigned int faceCount = (m - 1)*(n - 1) * 2; // Create vertices float halfWidth = width * 0.5f; float halfDepth = depth * 0.5f; float dx = width / (n - 1); float dz = depth / (m - 1); float du = 1.0f / (n - 1); float dv = 1.0f / (m - 1); vertices.resize(vertexCount); for (unsigned int i = 0; i < m; ++i) { float z = halfDepth - i * dz; for (unsigned int j = 0; j < n; ++j) { float x = -halfWidth + j * dx; vertices[i*n + j].position = glm::vec3(x, z, 0.0f); vertices[i*n + j].color = glm::vec3(0.0f, 1.0f, 0.0f); } } // create Indizes indices.resize(faceCount*3); unsigned int k = 0; for (unsigned int i = 0; i < m - 1; ++i) { for (unsigned int j = 0; j < n - 1; ++j) { indices[k + 0] = i * n + j; indices[k + 1] = i * n + j + 1; indices[k + 2] = (i + 1)*n + j; indices[k + 3] = (i + 1)*n + j; indices[k + 4] = i * n + j + 1; indices[k + 5] = (i + 1)*n + j + 1; k += 6; // next quad } } return Mesh(instance, vertices, indices, VK_POLYGON_MODE_LINE , VK_PRIMITIVE_TOPOLOGY_LINE_LIST); }
Why This Failed
The original code was built for triangle lists (standard in DirectX 12 mesh setups), but when using VK_PRIMITIVE_TOPOLOGY_LINE_LIST, the index structure didn't map correctly. Each quad was split into two triangles (6 indices total), which in line list mode only rendered partial edges of the quad. Worse, the outermost edges of the grid (the final row and column of lines) weren't included in any of the triangle-based indices, leading to the missing lines.
Fixed Implementation
Here's the revised index buffer code that resolves the issue:
// create Indizes indices.resize(faceCount * 4); unsigned int k = 0; for (unsigned int i = 0; i < m - 1; ++i) { for (unsigned int j = 0; j < n - 1; ++j) { indices[k + 0] = i * n + j; indices[k + 1] = i * n + (j + 1); indices[k + 2] = i * n + (j + 1); indices[k + 3] = (i + 1) * n + j + 1; indices[k + 4] = (i + 1) * n + j + 1; indices[k + 5] = (i + 1) * n + j; indices[k + 6] = (i + 1) * n + j; indices[k + 7] = i * n + j; k += 8; } }
Key Changes
- Index Buffer Resize: We now allocate
faceCount * 4indices (8 indices per quad, since each line segment needs 2 indices and each quad has 4 edges). - Explicit Line Segments: Instead of defining triangles, we explicitly list each edge of the quad as a pair of indices for the line list:
- Top horizontal edge of the quad
- Right vertical edge of the quad
- Bottom horizontal edge of the quad
- Left vertical edge of the quad
- Index Increment: Updated
k += 8to step through the 8-index block for each quad.
This ensures every edge of the grid is properly rendered, including the previously missing lines along the X and Y axes.
内容的提问来源于stack exchange,提问作者Pixma

