Vulkan and Instancing

Hi!
I’m actually trying to render a scene using instancing. The problem is that I’ve been trying for about a week now and it doesn’t seems to be enough…so I’ll give all the step I think should be accomplished to setup instancing with vulkan:

1-setup the Binding Description:

	
               VkVertexInputBindingDescription instanceBindingDescription = {};
		instanceBindingDescription.binding = 1;
		instanceBindingDescription.stride = sizeof(glm::mat4);
		instanceBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;

2-setup the attribute Description: inspire rom here


		attributeDescriptions[2].binding = 0;
		attributeDescriptions[2].location = 4;
		attributeDescriptions[2].format = VK_FORMAT_R32G32B32_SFLOAT;
		attributeDescriptions[2].offset = 0;

		attributeDescriptions[3].binding = 0;
		attributeDescriptions[3].location = 5;
		attributeDescriptions[3].format = VK_FORMAT_R32G32B32_SFLOAT;
		attributeDescriptions[3].offset = sizeof(glm::vec4);

		attributeDescriptions[4].binding = 0;
		attributeDescriptions[4].location = 6;
		attributeDescriptions[4].format = VK_FORMAT_R32G32B32_SFLOAT;
		attributeDescriptions[4].offset = 2*sizeof(glm::vec4);

		attributeDescriptions[5].binding = 0;
		attributeDescriptions[5].location = 7;
		attributeDescriptions[5].format = VK_FORMAT_R32G32B32_SFLOAT;
		attributeDescriptions[5].offset = 4*sizeof(glm::vec4);

(comes the buffer creation to store all my modified model matrix…I think am i right here)
3-Setup the Descriptor set layout:

VkDescriptorSetLayoutBinding instanceLayoutBinding = {};
		instanceLayoutBinding.binding = 2;
		instanceLayoutBinding.descriptorCount = 1;
		instanceLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
		instanceLayoutBinding.pImmutableSamplers = nullptr;
		instanceLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;

4-setup the descriptor set:

descriptorWrites[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
		descriptorWrites[2].dstSet = descriptorSet;
		descriptorWrites[2].dstBinding = 2;
		descriptorWrites[2].dstArrayElement = 0;//have a doubt here. should it be the amount of instanced object?
		descriptorWrites[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
		descriptorWrites[2].descriptorCount = 1;
		descriptorWrites[2].pBufferInfo = &instanceBufferInfo;

5-Finally the commands buffer:

vkCmdBindVertexBuffers(commandBuffers[i], 1, 1, &instanceBuffer, offsets);
			vkCmdDraw(commandBuffers[i], static_cast<uint32_t>(vertices.size()), instanceAmount, 0, 0);

and my vertex shader looks like:

#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;


layout(location = 0) in vec3 inPosition;
//layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 4) in mat4 instanceModels;

layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;

out gl_PerVertex {
    vec4 gl_Position;
};

void main() {
    gl_Position = ubo.proj * ubo.view * instanceModels * vec4(inPosition , 1.0);
    //fragColor = inColor;
    fragTexCoord = inTexCoord;
}

Without adding instancing, my original object is a cube. When i try to draw multiple cubes via instancing, all i get is my cube’s triangles which aren t where the should be…no sight of any other cube.

If someone can check my code and tell me which step(s) failed in or which step(s) I’ve forgotten. And why not some links…
Thanks, for the reading.
(I’m French so sorry for my english…)

attributeDescriptions[5].binding = 0;
attributeDescriptions[5].location = 7;
attributeDescriptions[5].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[5].offset = 4*sizeof(glm::vec4);

Shouldn’t the offset be 3*sizeof(glm::vec4) in here? Otherwise you reference values outside of what you actually pass.

In general: If you want to do instancing using matrices you’re better of passing your instance data using a SSBO instead, as vertex attribute input count is limited with a lower (per spec) limit of 16.

yep, finally did it
thanks :smiley:
My Xmas gift x)

It has “nothing” to do with the original post, but is it better to create a unique vertex/fragment shader and use multiple entry points? Or 1 shader = 1 entry point?

So why did you post it in this thread rather than a new one? Do you think we’re running out of threads? :wink:

I don’t know what you mean by that. You can create SPIR-V binaries that have multiple entrypoints. But once you build a program out of them, each shader stage for that program has exactly one entrypoint.