簡體   English   中英

在 Vulkan 中實現“實例化渲染”的正確方法是什么?

[英]What's the correct way to implement "Instanced rendering" in Vulkan?

我目前正在嘗試有效地渲染多個立方體,所以我想知道如何在 Vulkan 中使用這種“實例化渲染”。

我目前只知道 2 種渲染大量(相同)對象的方法:

1) 多個描述符集;

2) 具有動態統一/動態偏移的單個 DescriptorSet;

在第一種情況下,大量內存被浪費了,因為每個立方體只需要一個不同的模型矩陣,但每個立方體仍然使用整個 DescriptorSet:此外,因為我每幀都注冊一個新的命令緩沖區,每個立方體花費了我 2 ' Cmd' 調用:

vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, descriptorSet, 0, nullptr);
vkCmdDraw(commandBuffer, numberOfVertices, 1, 0, 0);

但是,對於很多多維數據集來說,這會導致 CPU 負載相當大,並且會浪費內存。

在第二種情況下,我只需要一個 DescriptorSet,將模型矩陣注冊為動態統一並用所有模型矩陣填充它; 但是,我仍然需要(稍加修改)對每個多維數據集進行相同的 2 個“Cmd”調用:

vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, descriptorSet, 1, index);
vkCmdDraw(commandBuffer, numberOfVertices, 1, 0, 0);

和以前一樣,對於很多多維數據集,盡管使用獨特的 DescriptorSet 節省了大量內存,但 CPU 負載仍然困擾着我。

所以我聽說過這個“實例化渲染”,它應該以某種方式告訴一個命令來繪制所有的立方體,為它提供一個模型矩陣的集合(可能仍然是一個緩沖區)。

如何做到這一點,防止我的程序使用單個調用在單個命令緩沖區中注冊數千個“Cmd”? 謝謝。

您將頂點屬性之一設置為VkVertexInputBindingDescription::inputRate == VK_VERTEX_INPUT_RATE_INSTANCE 然后你把必要的數據來偏移和旋轉到屬性中。

另一種選擇是使用內置變量的頂點着色器,該變量指示正在處理的實例。 您可以使用它來索引 SSBO 或 UBO 以獲取您需要的數據。

在您的代碼中:

vkCmdDrawIndexed(command_buffer, indices_size, instance_count, 0, 0, instance_first_index);

  • instance_count:要繪制的實例數
  • instance_first_index:第一個實例將具有此 ID

在你的頂點着色器就可以使用可變gl_InstanceIndex其中包含實例ID開始instance_first_index

[1] https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdDrawIndexed.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM