在 Vulkan 中处理多个相机

Handle multiply cameras in Vulkan

我正在尝试使用不同的相机实现渲染。 当我只使用一台相机时,一切正常。但是当我有两个具有不同转换的相机时,渲染无法正常工作,第一个场景是用第二个相机转换渲染的。

void Setup() {
    ...
    // create uniform buffer (vmaCreateBuffer)
    global_uniform_buffer = ... 
    // allocate descriptor set 
    global_descriptor_set = ... 
    // write descriptor set
    ...
}

void SetCameraProperties(Camera* camera) {
    auto proj_view = camera->GetProjectionMatrix() * camera->GetViewMatrix();
    global_uniform_buffer->update(&proj_view, sizeof(glm::mat4));
}

void BindGlobalDescriptorSet(vk::CommandBuffer cmd, vk::PipelineLayout pipeline_layout) {
    cmd.bindDescriptorSets(
        vk::PipelineBindPoint::eGraphics, 
        pipeline_layout, 
        0, 
        { global_descriptor_set }, 
        {}
    );
}

void DrawScene() {
    ...
    cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
    BindGlobalDescriptorSet(cmd, pipeline_layout);
    cmd.bindVertexBuffers(0, vtx->handle, vk::DeviceSize{0});
    cmd.bindIndexBuffer(idx->handle, vk::DeviceSize{0}, vk::IndexType::eUint16);
    cmd.drawIndexed(3, 1, 0, 0, 0);
    ...
}

void Loop() {
    ... // begin render pass with scene framebuffer
    SetCameraProperties(Editor::Get()->GetEditorCamera()):
    DrawScene();
    ... // end previous render pass
    ... // begin render pass with game frame buffer
    SetCameraProperties(CameraSystem::Get()->GetMainCamera()):
    DrawScene();
    ... // end previous render pass
    ... // present
}

查看您的代码,您在创建命令缓冲区时更改了两个绘图调用之间的相同统一缓冲区。但是绑定统一缓冲区的内容在提交时而不是在创建时被消耗。因此,当您提交命令缓冲区时,它会使用上次更新的统一缓冲区内容。

所以您当前的设置在 Vulkan 中无法以这种方式工作。为了使这项工作有效,您可以为每个相机使用一个 UBO,或者为相机使用一个具有单独范围的动态 UBO。