Skip to content

Commit

Permalink
Added support for loading colors from glTF files
Browse files Browse the repository at this point in the history
Initialize base color
Removed assert that would trigger on some basic glTFs
Refs KhronosGroup#848
  • Loading branch information
SaschaWillems committed Jan 27, 2024
1 parent 4bad03b commit 036fd41
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions framework/api_vulkan_sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct Vertex
glm::vec2 uv;
glm::vec4 joint0;
glm::vec4 weight0;
glm::vec3 color;
};

/**
Expand Down
36 changes: 33 additions & 3 deletions framework/gltf_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,6 @@ std::unique_ptr<sg::Scene> GLTFLoader::read_scene_from_file(const std::string &f
if (!err.empty())
{
LOGE("Error loading gltf model: {}.", err.c_str());

return nullptr;
}

Expand Down Expand Up @@ -1032,7 +1031,12 @@ sg::Scene GLTFLoader::load_scene(int scene_index)
auto node_it = traverse_nodes.front();
traverse_nodes.pop();

assert(node_it.second < nodes.size());
// @todo: this crashes on some very basic scenes
//assert(node_it.second < nodes.size());
if (node_it.second >= nodes.size())
{
continue;
}
auto &current_node = *nodes[node_it.second];
auto &traverse_root_node = node_it.first;

Expand Down Expand Up @@ -1097,6 +1101,8 @@ std::unique_ptr<sg::SubMesh> GLTFLoader::load_model(uint32_t index, bool storage
const float *uvs = nullptr;
const uint16_t *joints = nullptr;
const float *weights = nullptr;
const float *colors = nullptr;
uint32_t color_component_count{4};

// Position attribute is required
auto &accessor = model.accessors[gltf_primitive.attributes.find("POSITION")->second];
Expand All @@ -1118,6 +1124,14 @@ std::unique_ptr<sg::SubMesh> GLTFLoader::load_model(uint32_t index, bool storage
uvs = reinterpret_cast<const float *>(&(model.buffers[buffer_view.buffer].data[accessor.byteOffset + buffer_view.byteOffset]));
}

if (gltf_primitive.attributes.find("COLOR_0") != gltf_primitive.attributes.end())
{
accessor = model.accessors[gltf_primitive.attributes.find("COLOR_0")->second];
buffer_view = model.bufferViews[accessor.bufferView];
colors = reinterpret_cast<const float *>(&(model.buffers[buffer_view.buffer].data[accessor.byteOffset + buffer_view.byteOffset]));
color_component_count = accessor.type == TINYGLTF_PARAMETER_TYPE_FLOAT_VEC3 ? 3 : 4;
}

// Skinning
// Joints
if (gltf_primitive.attributes.find("JOINTS_0") != gltf_primitive.attributes.end())
Expand Down Expand Up @@ -1173,7 +1187,20 @@ std::unique_ptr<sg::SubMesh> GLTFLoader::load_model(uint32_t index, bool storage
vert.pos = glm::vec4(glm::make_vec3(&pos[v * 3]), 1.0f);
vert.normal = glm::normalize(glm::vec3(normals ? glm::make_vec3(&normals[v * 3]) : glm::vec3(0.0f)));
vert.uv = uvs ? glm::make_vec2(&uvs[v * 2]) : glm::vec3(0.0f);

if (colors)
{
switch (color_component_count)
{
case 3:
vert.color = glm::vec4(glm::make_vec3(&colors[v * 3]), 1.0f);
case 4:
vert.color = glm::make_vec4(&colors[v * 4]);
}
}
else
{
vert.color = glm::vec4(1.0f);
}
vert.joint0 = has_skin ? glm::vec4(glm::make_vec4(&joints[v * 4])) : glm::vec4(0.0f);
vert.weight0 = has_skin ? glm::make_vec4(&weights[v * 4]) : glm::vec4(0.0f);
vertex_data.push_back(vert);
Expand Down Expand Up @@ -1365,6 +1392,9 @@ std::unique_ptr<sg::PBRMaterial> GLTFLoader::parse_material(const tinygltf::Mate
{
auto material = std::make_unique<sg::PBRMaterial>(gltf_material.name);

// Initialize base color to 1.0f as per glTF spec
material->base_color_factor = glm::vec4(1.0f);

for (auto &gltf_value : gltf_material.values)
{
if (gltf_value.first == "baseColorFactor")
Expand Down

0 comments on commit 036fd41

Please sign in to comment.