Vulkan에서 인스턴스화 된 메쉬 렌더링을 구현하려고합니다.Vulkan vkCmdDrawIndexed는 처음에만 VertexBuffer의 값을 사용했습니다.
내 문제는 Vulkan이 바인드 된 VertexBuffer의 첫 번째 Vertex 만 사용하고 모든 Indices의 Value를 복제한다는 것입니다. 출력 RenderDoc :
RenderDoc output Duplicated Vertex Input
다음은 올바른 값이어야한다는 {{<inPosition>
는}, {<inColor>
}, {<inTexCoord>
는}} :
const vkf::Vertex vertices[] = {
{ { -0.2f, -0.5f, 0.0f },{ 1.0f, 0.0f, 0.0f },{ 1.0f, 0.0f } },
{ { 0.5f, -0.5f, 0.0f },{ 0.0f, 1.0f, 0.0f },{ 0.0f, 0.0f } },
{ { 0.5f, 0.5f, 0.0f },{ 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f } },
{ { -0.5f, 0.5f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 1.0f, 1.0f } }
};
가 나는 VertexBuffer에 여러 번 확인하고 그것을 한 올바른 값을 포함합니다.
다음은 내 CommandBuffer의 작성에서 냈다입니다 :
vkCmdBindPipeline(m_commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.agents);
VkBuffer vertexBuffers[] = { models.agent.verticesBuffer };
VkBuffer instanceBuffers[] = { m_instanceBuffer.buffer };
VkDeviceSize offsets[] = { 0 };
vkCmdBindVertexBuffers(m_commandBuffers[i], 0, 1, vertexBuffers, offsets);
vkCmdBindVertexBuffers(m_commandBuffers[i], 1, 1, instanceBuffers, offsets);
vkCmdBindIndexBuffer(m_commandBuffers[i], models.agent.indexBuffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdBindDescriptorSets(m_commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayouts.pipelineLayoutAgent, 0, 1, &descriptorSets.agent, 0, nullptr);
vkCmdDrawIndexed(m_commandBuffers[i], static_cast<uint32_t> (models.agent.indexCount), 5, 0, 0, 0);
나의 첫번째 가정 내 바인딩 설명을 잘못이었다. 하지만 오류가 표시되지 않습니다.
bindingDescription = {};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
왜 버퍼의 첫 번째 값만 사용됩니까?
EDIT :
InstanceData :
struct InstanceData
{
glm::vec3 pos;
glm::vec3 rot;
float scale;
static VkVertexInputBindingDescription getBindingDescription()
{
VkVertexInputBindingDescription bindingDescription = {};
bindingDescription.binding = INSTANCING_BIND_ID;
bindingDescription.stride = sizeof(InstanceData);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
return bindingDescription;
}
};
전체 VkPipelineVertexInputStateCreateInfo :
std::vector<VkVertexInputBindingDescription> bindingDesciption = {};
std::vector<VkVertexInputAttributeDescription> attributeDescriptions = {};
bindingDesciption = {
models.agent.bindingDescription,
InstanceData::getBindingDescription()
};
attributeDescriptions =
{
vertexInputAttributeDescription(VERTEX_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkf::Vertex, pos)),
vertexInputAttributeDescription(VERTEX_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkf::Vertex, color)),
vertexInputAttributeDescription(INSTANCING_BIND_ID, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)),
vertexInputAttributeDescription(VERTEX_BIND_ID, 3, VK_FORMAT_R32G32_SFLOAT, offsetof(vkf::Vertex, texCoord))
};
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(bindingDesciption.size());
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
vertexInputInfo.pVertexBindingDescriptions = bindingDesciption.data();
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
EDIT 2
#define VERTEX_BIND_ID 0
#define INSTANCING_BIND_ID 1
,
편집 3 : 나는 VulkanMemoryAllocator를 사용하고 있습니다.
copyBuffer(stagingVertexBuffer, verticesBuffer, vertexBufferSize);
void Base::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
VkCommandBuffer commandBuffer = beginSingleTimeCommands();
VkBufferCopy copyRegion = {};
copyRegion.dstOffset = 0;
copyRegion.srcOffset = 0;
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region);
endSingleTimeCommands(commandBuffer);
}
I : 이것은 내가 준비에서 내 버퍼를 transfair 어떻게
createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);
VkBuffer createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaMemoryUsage vmaUsage)
{
VkBuffer buffer;
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = vmaUsage;
allocCreateInfo.flags = 0;
VmaAllocationInfo allocInfo;
if (vmaCreateBuffer(m_allocator, &bufferInfo, &allocCreateInfo, &buffer, &m_allocation, &allocInfo) != VK_SUCCESS)
{
throw std::runtime_error("failed to create Buffer!");
}
return buffer;
}
:
memcpy(mappedStaging, vertices, vertexBufferSize);
버퍼를 만들기 : 는
size_t vertexBufferSize = sizeof(vkf::Vertex) *_countof(vertices);
createStagingBuffer(vertexBufferSize);
VkBuffer createStagingBuffer(VkDeviceSize size)
{
VkBuffer buffer;
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = size;
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT;
VmaAllocationInfo allocInfo = {};
if (vmaCreateBuffer(m_allocator, &bufferInfo, &allocCreateInfo, &buffer, &m_allocation, &allocInfo) != VK_SUCCESS)
{
throw std::runtime_error("failed to create Buffer!");
}
return buffer;
}
복사 정점 버퍼를 준비 만들기 데이터가 스테이징 버퍼에 있고 vertexBuffer에서도 createBuffer Prozess를 수정 한 후 여러 번 검사했습니다. 그들은 올바르게 거기에 저장됩니다.
전체'VkPipelineVertexInputStateCreateInfo'을 보여주십시오. 또한 버퍼 데이터를 설정/전송하는 방법. 또한 버텍스 쉐이더 인터페이스 블록이 좋을 것입니다. – krOoze
추신 : 최신 유효성 검사 레이어를 사용하도록 설정 했습니까? – krOoze
내 게시물에 전체 VkPipelineVertexInputStateCreateInfo를 추가했습니다. VK_LAYER_LUNARG_standard_validation 확장 기능이 활성화되었습니다. –