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