두 개의 4x4 행렬을 포함하는 균일 버퍼 객체를 버텍스 쉐이더에 전달하고 싶습니다. Vulkan UBO가 잘못 전달되었습니다.
struct PerRenderUBO
{
glm::mat4 viewProjection;
glm::mat4 projection; //unused
};
와 GLSL에서
: 최대한 빨리 내 UBO 구조체에서 하나 명 이상의 멤버를 선언하지만layout(std140, set = 0, binding = 0) uniform UBO {
mat4 viewProjection;
mat4 projection; //unused
} perRenderUBO;
은, 일부 개체가 잘못 인해 그려 얻을 다음과 같이 나는 C++에서 구조체를 선언 한 잘못된 viewProjection 행렬에. PerRenderUBO 구조체와 GLSL 선언 모두에서 'projection'데이터 멤버를 주석 처리하면 모든 것이 올바르게 렌더링됩니다 (셰이더에서 투영을 사용하지 않았더라도).
이렇게하면 데이터 정렬에 문제가있는 것으로 생각됩니다. std140 주석으로 레이아웃을 선언했습니다. sizeof (PerRenderUBO)는 128을 반환합니다. '돌출'을 float로 선언하려고 시도했지만 문제가 지속됩니다.
/** Create Layout **/
vk::DescriptorSetLayoutBinding perRenderUBOBinding;
perRenderUBOBinding.binding = 0;
perRenderUBOBinding.descriptorCount = 1;
perRenderUBOBinding.descriptorType = vk::DescriptorType::eUniformBuffer;
perRenderUBOBinding.stageFlags = vk::ShaderStageFlagBits::eVertex;
perRenderUBOBinding.pImmutableSamplers = nullptr;
std::vector<vk::DescriptorSetLayoutBinding> bindings{perRenderUBOBinding};
vk::DescriptorSetLayoutCreateInfo createInfo;
createInfo.bindingCount = bindings.size();
createInfo.pBindings = bindings.data();
this->perRenderUBOLayout = vkDevice->createDescriptorSetLayout(createInfo);
/** Create host-visible and host-coherent buffer **/
vk::BufferCreateInfo bufferCreateInfo;
bufferCreateInfo.size = sizeof(PerRenderUBO);
bufferCreateInfo.usage = vk::BufferUsageFlagBits::eUniformBuffer;
bufferCreateInfo.sharingMode = vk::SharingMode::eExclusive;
bufferCreateInfo.queueFamilyIndexCount = queueFamilyIndices.size();
bufferCreateInfo.pQueueFamilyIndices = queueFamilyIndices.data();
this->buffer = vkDevice->createBuffer(bufferCreateInfo);
vk::MemoryRequirements memoryRequirements = vkDevice->getBufferMemoryRequirements(this->buffer);
//allocates device memory as proposed in the specification (10.2 Device Memory)
this->bufferDeviceMemory = allocate(memoryRequirements, vk::MemoryPropertyFlags{vk::MemoryPropertyFlagBits::eHostVisible} | vk::MemoryPropertyFlags{vk::MemoryPropertyFlagBits::eHostCoherent});
vkDevice->bindBufferMemory(this->buffer, this->bufferDeviceMemory, 0);
this->descriptorPool = ...//create a descriptor pool for 1 uniform buffer
this->descriptorSet = ...//allocate descriptor set for above layout
vk::DescriptorBufferInfo bufferInfo;
bufferInfo.buffer = this->buffer;
bufferInfo.offset = 0;
bufferInfo.range = sizeof(PerRenderUBO);
vk::WriteDescriptorSet writeDescriptorSet;
writeDescriptorSet.dstSet = *this->descriptorSet;
writeDescriptorSet.dstBinding = 0;
writeDescriptorSet.dstArrayElement = 0;
writeDescriptorSet.descriptorType = vk::DescriptorType::eUniformBuffer;
writeDescriptorSet.descriptorCount = 1;
writeDescriptorSet.pBufferInfo = &bufferInfo;
writeDescriptorSet.pImageInfo = nullptr;
writeDescriptorSet.pTexelBufferView = nullptr;
vkDevice->updateDescriptorSets({writeDescriptorSet}, {});
차 DRAW 명령 버퍼를 실행하기 전에 다음과 같이, I가 PerRenderUBO 대한 버퍼를 업데이트 :
std::vector<PerRenderUBO> data; //contains 1 instance of PerRenderUBO
vk::DeviceSize offset = 0;
vk::DeviceSize size = data.size() * sizeof(PerRenderUBO);
void* memory = vkDevice->mapMemory(this->bufferDeviceMemory, offset, size);
std::memcpy(memory, data.data(), size);
this->deviceMemory->unmap();
I '은 다음
이 설명자 세트 생성의 가장 중요한 부분이다 버퍼 크기와 오프셋을 여러 번 확인했는데 모두 괜찮아 보입니다. 또한 동일한 설명자 세트가 모든 그리기 명령에 바인딩되고 일부 객체가 올바르게 렌더링되기 때문에 버퍼 자체의 데이터가 정확해야한다고 생각합니다. 내가 무엇이 누락 되었습니까?
실제로 ubo 데이터를 업로드하는 부분을 추가 할 수 있습니까? –
버퍼 생성 및 버퍼 업데이트 코드를 추가했습니다. – user3067395
하나의 PerRenderUBO 인스턴스 만 있지만 여러 객체 렌더링에 대해 이야기합니다. 커맨드 버퍼 당 하나의 드로잉이 있습니까 (커맨드 버퍼를 제출하기 직전에/memcpy/unmap을 맵핑했기 때문에)? 그렇다면 무승부 N이 완료되기 전에 드로 N + 1에 대한 UBO 내용을 덮어 쓰지 않도록 보장하는 것은 무엇입니까? –