How to draw meshes with different material parameters in one render pass

I want to render two meshes with same shader set, but using different values of uniform parameters, such as different specular coefficient. How can I draw these two meshes in one render pass.

I failed to try the following render sequence:


for(auto& mesh : meshes)
    DrawIndexed(mesh.indexCount, 1, 0, 0, 0)


I would appreciate an idea or a suggestion.

You can use VkDescriptoSet with dynamic offsets

There are many ways do pass material data. The easiest and most straight forward way would be using push constants. Another one is having separate descriptors per material, and then binding those descriptors before the draw call. If you are on more modern hardware you may also go bindless, put all materials into one large descriptor and index by e.g. a push constant or some other parameter or even go with a material buffer.

1 Like

Thanks for your explanation. To my understanding, using push constants to set material parameters is done by recording a command vkCmdPushConstants, it can change the material parameters internal executing command buffer. So shader can receive correct parameter values by recording vkCmdPushConstants before draw call. If there are multiple draw calls in one render pass, using descriptors can not pass the parameter value only for the current draw call. Because vkUpdateDescriptorSets will invalid the command buffer used to bind the descriptor sets, which will disenable recording next call. Therefore, I have to use separate descriptor per material.

What I implement is like your second method, I use uniform buffer array where each element is a set of material parameters, and add an additional input attribute named “material id” to index the corresponding uniform buffer.

I am not sure if it is a formal or optimal implementation. I am still trying to dig into the implementation of game engine.