Vertex layout

As stated before you need to setup a vertex layout for the meshes in your loaded scene. The reason for this is that a vertex shader usually receives vertex attributes as input data per vertex during rendering. Those values can then be used for calculation or get forwarded via interpolation to later shader stages. Here is a vertex shader to manage the loaded geometry of the scene:

shaders/shader.vert

#version 450

layout(location = 0) in vec3 inPosition; // vertex position
layout(location = 1) in vec3 inNormal;   // vertex normal
layout(location = 2) in vec2 inUV;       // vertex uv-coordinate

layout(location = 0) out vec3 passNormal; // normal to interpolate
layout(location = 1) out vec2 passUV;     // uv-coordinate to interpolate

layout( push_constant ) uniform constants {
    mat4 mvp; // model-view-projection matrix
};

void main()	{
  // transform the vertex position from model-space into projection-space
  gl_Position = mvp * vec4(inPosition, 1.0);
  
  // pass the normal and the uv-coordinate of the individual vertex to the 
  // next stage in pipeline...
  passNormal  = inNormal;
  passUV      = inUV;
}

You might notice that the order of the vertex attributes used as inputs here in this shader is the same order as the vertex attribute types during the scene loading. This is intentional because if their orders match, their indices will match their locations specified in the vertex shader. Therefore the graphics pipeline is able to use the vertex buffers from the scenes meshes properly.

For a graphics pipeline you have to specify the vertex layout of your vertex buffers. Because the shaders have attachments in the exact order of the vertex attributes loaded from the scene, you can just use the indices as binding locations as shown below.

const auto vertexAttachments = shaderProgram.getVertexAttachments();
vkcv::VertexBindings bindings;

// filling a list of vertex bindings for the layout
for (size_t i = 0; i < vertexAttachments.size(); i++) {
  // each vertex attachment (input) represents one vertex binding using
  // i as the binding location...
  bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] }));
}

// the vertex layout containing the defined bindings
const vkcv::VertexLayout vertexLayout { bindings };

vkcv::GraphicsPipelineHandle gfxPipeline = core.createGraphicsPipeline(
  vkcv::GraphicsPipelineConfig(
    shaderProgram, // shader program
    renderPass,    // render pass
    vertexLayout,  // vertex layout
    {}             // ...
  )
);

Now the geometry can be processed by your graphics pipeline. But you still need the required parts for proper shading to get the wanted visuals. The next part takes care of this.

Previous

Next

Popular posts from this blog

Introduction

Application development

First setup