diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
index c7dd11e0c60dbd306fd881d57624d9a259331b94..f1ca666b04c4e905e96f41c63dbeda41b7739846 100644
--- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
@@ -282,6 +282,7 @@ int loadScene(const std::string &path, Scene &scene){
 
         for(int j = 0; j < objectMesh.primitives.size(); j++){
             fx::gltf::Primitive const &objectPrimitive = objectMesh.primitives[j];
+            vertexAttributes.clear();
             vertexAttributes.reserve(objectPrimitive.attributes.size());
 
             for (auto const & attrib : objectPrimitive.attributes) {
@@ -419,7 +420,39 @@ int loadScene(const std::string &path, Scene &scene){
         }
     }
 
-    // TODO fill materials struct and vector
+    if (sceneObjects.materials.size() > 0){
+        materials.reserve(sceneObjects.materials.size());
+
+        for (int l = 0; l < sceneObjects.materials.size(); l++){
+            fx::gltf::Material material = sceneObjects.materials[l];
+            materials.push_back({
+               0, // TODO; macros not yet defined
+               material.pbrMetallicRoughness.baseColorTexture.index,
+               material.pbrMetallicRoughness.metallicRoughnessTexture.index,
+               material.normalTexture.index,
+               material.occlusionTexture.index,
+               material.emissiveTexture.index,
+               {
+                   material.pbrMetallicRoughness.baseColorFactor[0],
+                   material.pbrMetallicRoughness.baseColorFactor[1],
+                   material.pbrMetallicRoughness.baseColorFactor[2],
+                   material.pbrMetallicRoughness.baseColorFactor[3]
+               },
+               material.pbrMetallicRoughness.metallicFactor,
+               material.pbrMetallicRoughness.roughnessFactor,
+               material.normalTexture.scale,
+               material.occlusionTexture.strength,
+               {
+                   material.emissiveFactor[0],
+                   material.emissiveFactor[1],
+                   material.emissiveFactor[2]
+               }
+
+            });
+            printf("baseColor index=%d normal=%d metallic factor=%f\n",
+                   materials[l].baseColor, materials[l].normal, materials[l].metallicFactor);
+        }
+    }
 
     scene = {
             meshes,
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 193b640ab0464503a070a42c06e7da59e7dbdbf0..d3fd8828e28b98d4a3cd9b54ea895832afc35647 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -46,19 +46,19 @@ int main(int argc, const char** argv) {
 	assert(mesh.vertexGroups.size() > 0);
 	auto vertexBuffer = core.createBuffer<uint8_t>(
 			vkcv::BufferType::VERTEX,
-			mesh.vertexGroups[0].vertexBuffer.data.size(),
+			mesh.vertexGroups[2].vertexBuffer.data.size(),
 			vkcv::BufferMemoryType::DEVICE_LOCAL
 	);
 	
-	vertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data);
+	vertexBuffer.fill(mesh.vertexGroups[2].vertexBuffer.data);
 
 	auto indexBuffer = core.createBuffer<uint8_t>(
 			vkcv::BufferType::INDEX,
-			mesh.vertexGroups[0].indexBuffer.data.size(),
+			mesh.vertexGroups[2].indexBuffer.data.size(),
 			vkcv::BufferMemoryType::DEVICE_LOCAL
 	);
 	
-	indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data);
+	indexBuffer.fill(mesh.vertexGroups[2].indexBuffer.data);
 
 	// an example attachment for passes that output to the window
 	const vkcv::AttachmentDescription present_color_attachment(
@@ -93,7 +93,7 @@ int main(int argc, const char** argv) {
 	triangleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX);
 	triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT);
 	
-	auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes;
+	auto& attributes = mesh.vertexGroups[2].vertexBuffer.attributes;
 	
 	std::sort(attributes.begin(), attributes.end(), [](const vkcv::VertexAttribute& x, const vkcv::VertexAttribute& y) {
 		return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type);
@@ -116,7 +116,7 @@ int main(int argc, const char** argv) {
 		windowWidth,
 		windowHeight,
 		trianglePass,
-		mesh.vertexGroups[0].vertexBuffer.attributes,
+		mesh.vertexGroups[2].vertexBuffer.attributes,
 		{ core.getDescriptorSetLayout(set, 0) });
 	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
 	
@@ -127,7 +127,7 @@ int main(int argc, const char** argv) {
 	
 	// FIXME There should be a test here to make sure there is at least 1
 	// texture in the mesh.
-	vkcv::asset::Texture &tex = mesh.textures[0];
+	vkcv::asset::Texture &tex = mesh.textures[2];
 	vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, tex.w, tex.h);
 	texture.fill(tex.data.data());
 
@@ -139,9 +139,9 @@ int main(int argc, const char** argv) {
 	);
 
 	std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[0].offset, vertexBuffer.getHandle() },
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[1].offset, vertexBuffer.getHandle() },
-		{ mesh.vertexGroups[0].vertexBuffer.attributes[2].offset, vertexBuffer.getHandle() }
+		{ mesh.vertexGroups[2].vertexBuffer.attributes[0].offset, vertexBuffer.getHandle() },
+		{ mesh.vertexGroups[2].vertexBuffer.attributes[1].offset, vertexBuffer.getHandle() },
+		{ mesh.vertexGroups[2].vertexBuffer.attributes[2].offset, vertexBuffer.getHandle() }
 	};
 
 	vkcv::DescriptorWrites setWrites;
@@ -168,7 +168,7 @@ int main(int argc, const char** argv) {
 			&mvp,
 			vertexBufferBindings,
 			indexBuffer.getHandle(),
-			mesh.vertexGroups[0].numIndices,
+			mesh.vertexGroups[2].numIndices,
 			set,
 			0
 		);