Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm currently trying to render multiple cubes efficiently, so I'd like to know how to use this "Instanced Rendering" in Vulkan.

I currently know of only 2 ways of rendering a lot of (identical) objects:

1) Multiple DescriptorSets;

2) Single DescriptorSet with Dynamic Uniforms / dynamic offsets;

In the first case, a lot of memory is wasted because the cubes only need a different model matrix each, but still using an entire DescriptorSet each: also, because I'm registering a new command buffer each frame, every cube cost me 2 'Cmd' calls:

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

But, for a lot of cubes, this results in a not insignificant CPU load, and a waste of memory.

In the second case, I only need a single DescriptorSet, registering the model matrix as a Dynamic Uniform and filling it with all the model matrices; However, I still need (with little modifications) the same 2 'Cmd' calls for each cube:

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

As before, for a lot of cubes, despite the huge memory save for using a unique DescriptorSet, the CPU load still bothers me.

So I heard about this "Instanced rendering", that should somehow tell with a single command to draw all the cubes, providing it a collection of model matrices (Probably still a Buffer).

How to do this, preventing my program to register thousands of 'Cmd' in a single command buffer, using a single call? Thanks.

like image 789
ShockCoding Avatar asked Feb 10 '19 18:02

ShockCoding


People also ask

What is instance instance rendering?

Instanced rendering means that we can render multiple instances in a single draw call and provide each instance with some unique attributes. We are going to cover two methods for doing that. In the first method instance specific attributes (e.g. WVP matrix) go into a seperate vertex buffer.

Does Vulkan rendering make your game more performant?

We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuitof Happiness. Folks generally make the mistake of assuming that writing a game using the Vulkan rendering API will make your game more performant.

How do I use Vulkan?

With Vulkan, you need to fill all of it out by hand.   This includes things like the various shader stages you want to use (Vertex, Geometry, Fragment, etc), render passes you want to use, line widths, viewports sizes, blending, etc. Command Buffers– OpenGL and DirectX 11 both use a graphics context to allow you to issue commands to the GPU.

Is there a way to render a lot of objects?

I currently know of only 2 ways of rendering a lot of (identical) objects: 2) Single DescriptorSet with Dynamic Uniforms / dynamic offsets;


Video Answer


2 Answers

You set one of the vertex attributes to have VkVertexInputBindingDescription::inputRate == VK_VERTEX_INPUT_RATE_INSTANCE. Then you put the necessary data to offset and rotate into the attibute.

Another option is to use the vertex shader built in variable which indicates which instance that is being processed. You can use that to index into a SSBO or UBO to get the data you need.

like image 181
ratchet freak Avatar answered Nov 15 '22 01:11

ratchet freak


in your code:

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

  • instance_count: number of instances to draw
  • instance_first_index: first instance will have this id

in your vertex shader you can then use variable gl_InstanceIndex which contains the instance id starting with instance_first_index

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

like image 27
AdamM Avatar answered Nov 14 '22 23:11

AdamM