Sign in to follow this  

Vulkan Is Dynamic Draw Call Batching Still Relevant?

Recommended Posts

Hey, So I wanted to ask a simple question pertaining to dynamic batching , as in dynamically building vertex and index buffers to reduce draw calls. I wanted to know that in the age of Vulkan/DirectX12 , dynamic instancing, and compute shader based culling, is dynamic batching still relevant? I know that Engines such as Unreal Engine does not support dynamic instancing / dynamic batching , and Unity supports both. I'm currently building a somewhat open world game, so efficiency is of the greatest importance. Thanks.

Share this post

Link to post
Share on other sites

Dynamically Batching is still very relevant , it's just that it conflicts with instancing so using both is very difficult.

When working with a lot of unique objects batching holds the advantage, that is why it was popular with linear games. The only rule for batching is that it should share the same material/ shader.

Instancing has the advantage when you need a lot of one object, like grass, that repeat. So it's the one you want to focus on when making openworld games.


The best would be to use both, batching for unique locations and instancing for large openworld zones. However making a dynamic batch manager that doesn't conflict with instancing is very difficult and makes a engine difficult to use; Lumberyard is a good example.

Most engines like Unreal 4 instead opt for selective batching, by allowing developers to merge objects by hand.

Share this post

Link to post
Share on other sites

Thank you both for your responses. What I tend to dislike about Unity's approach is that , in my opinion, they can only dynamically batch really small meshes, it also seems that now that they support dynamic instancing, a mesh will use instancing before dynamic batching. Do you have any opinion on mesh merging / vertex pulling in comparison to the older batching techniques?

Share this post

Link to post
Share on other sites
I think ti's interesting if your use-cases have a bottleneck or performance issue which could be solved using this technique

Share this post

Link to post
Share on other sites

Thank you both for your responses. What I tend to dislike about Unity's approach is that , in my opinion, they can only dynamically batch really small meshes,

That is how it works you have 65 000 vertices per mesh, you can either have 65 000 single vertex meshes or one 65 000 vertices mesh. Unreal has the same limit except it's called the 64k polygon limit.

What it means is that when you load in a mesh more than 64k-65k vertices it will create a new batch. How many batches a game can use depends on the graphics card not the engine.


The reason Unity can only batch small meshes is because of UV maps and Smooth groups. A UV seam splits the vertices where it is assigned, in games this matters a lot because a single UV map can add as much as 30%-50% to the vertex count. Smooth groups often add 10%-20% vertices to the count.

So a simple 1000 vertices mesh with a UV map and only one smooth group is more like a 1500- 1800 vertices. And you end up getting a lot less meshes per batch than expected.


Do you have any opinion on mesh merging / vertex pulling in comparison to the older batching techniques?

My opinion on vertex pulling and mesh merging is that both are just different ways of batching. The performance gain and downsides is the same as batching.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Forum Statistics

    • Total Topics
    • Total Posts
  • Similar Content

    • By mark_braga
      I am looking at the SaschaWillems subpass example for getting some insight into subpass depdendencies but its hard to understand whats going on without any comments. Also there is not a lot of documentation on subpass dependencies overall.
      Looking at the code, I can see that user specifies the src subpass, dst subpass and src state, dst state. But there is no mention of which resource the dependency is on. Is a subpass dependency like a pipeline barrier. If yes, how does it issue the barrier? Is the pipeline barrier issued on all attachments in the subpass with the input src and dst access flags? Any explanation will really clear a lot of doubts on subpass dependencies.
      Thank you
    • By mark_braga
      I need to index into a texture array using indices which are not dynamically uniform. This works fine on NVIDIA chips but you can see the artifacts on AMD due to the wavefront problem. This means, a lot of pixel invocations get the wrong index value. I know you fix this by using NonUniformResourceIndex in hlsl. Is there an equivalent for Vulkan glsl?
      This is the shader code for reference. As you can see, index is an arbitrary value for each pixel and is not dynamically uniform. I fix this for hlsl by using NonUniformResourceIndex(index)
      layout(set = 0, binding = 0) uniform sampler textureSampler; layout(set = 0, binding = 1) uniform texture2D albedoMaps[256]; layout(location = 0) out vec4 oColor; void main() { uint index = calculate_arbitrary_texture_index(); vec2 texCoord = calculate_texcoord(); vec4 albedo = texture(sampler2D(albedoMaps[index], textureSampler), texCoord); oColor = albedo; } Thank you
    • By Mercesa
      As the title says, I am explicitly creating a too small descriptor pool, which should NOT support the resources I am going to allocate from it.
      std::array<vk::DescriptorPoolSize, 3> type_count; // Initialize our pool with these values type_count[0].type = vk::DescriptorType::eCombinedImageSampler; type_count[0].descriptorCount = 0; type_count[1].type = vk::DescriptorType::eSampler; type_count[1].descriptorCount = 0; type_count[2].type = vk::DescriptorType::eUniformBuffer; type_count[2].descriptorCount = 0; vk::DescriptorPoolCreateInfo createInfo = vk::DescriptorPoolCreateInfo() .setPNext(nullptr) .setMaxSets(iMaxSets) .setPoolSizeCount(type_count.size()) .setPPoolSizes(; pool = aDevice.createDescriptorPool(createInfo);  
      I have an allocation function which looks like this, I am allocating a uniform, image-combined sampler and a regular sampler. Though if my pool is empty this should not work?
      vk::DescriptorSetAllocateInfo alloc_info[1] = {}; alloc_info[0].pNext = NULL; alloc_info[0].setDescriptorPool(pool); alloc_info[0].setDescriptorSetCount(iNumToAllocate); alloc_info[0].setPSetLayouts(&iDescriptorLayouts); std::vector<vk::DescriptorSet> tDescriptors; tDescriptors.resize(iNumToAllocate); iDevice.allocateDescriptorSets(alloc_info,;  
    • By Mercesa
      When loading in a model with a lot of meshes that have different materials that contain different textures, how would you handle this in Vulkan?
      Is it possible to partially change a DescriptorSet with a WriteDescriptorSet object? Even if it is possible, it does not sound ideal to update the descriptor set for every mesh. I am aware of the boundless texture arrays in shader model 5.0+, but for now I want to keep it as simple as possible.
    • By khawk
      CRYENGINE has released their latest version with support for Vulkan, Substance integration, and more. Learn more from their announcement and check out the highlights below.
      Substance Integration
      CRYENGINE uses Substance internally in their workflow and have released a direct integration.
      Vulkan API
      A beta version of the Vulkan renderer to accompany the DX12 implementation. Vulkan is a cross-platform 3D graphics and compute API that enables developers to have high-performance real-time 3D graphics applications with balanced CPU/GPU usage. 

      Entity Components
      CRYENGINE has addressed a longstanding issue with game code managing entities within the level. The Entity Component System adds a modular and intuitive method to construct games.
      And More
      View the full release details at the CRYENGINE announcement here.

      View full story
  • Popular Now