Skip to content

Commit

Permalink
[Data/GltfLoad] Fixed textures & images pairing
Browse files Browse the repository at this point in the history
- The texture index was wrongly assumed to be the image index, while the latter is actually the textures' source field

- Fixes issue #64
  • Loading branch information
Razakhel committed Jan 21, 2024
1 parent bc919a3 commit db53b4a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 23 deletions.
52 changes: 38 additions & 14 deletions src/RaZ/Data/GltfLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,28 @@ std::pair<Image, Image> extractMetalnessRoughnessImages(const Image& metalRoughI
return { std::move(metalnessImg), std::move(roughnessImg) };
}

void loadMaterials(const std::vector<fastgltf::Material>& materials, const std::vector<std::optional<Image>>& images, MeshRenderer& meshRenderer) {
template <template <typename> typename OptionalT, typename TextureInfoT, typename FuncT>
void loadTexture(const OptionalT<TextureInfoT>& textureInfo,
const std::vector<fastgltf::Texture>& textures,
const std::vector<std::optional<Image>>& images,
const FuncT& callback) {
static_assert(std::is_base_of_v<fastgltf::TextureInfo, TextureInfoT>);

if (!textureInfo.has_value())
return;

const fastgltf::Optional<std::size_t>& imgIndex = textures[textureInfo->textureIndex].imageIndex;

if (!imgIndex.has_value() || !images[*imgIndex].has_value())
return;

callback(*images[*imgIndex]);
}

void loadMaterials(const std::vector<fastgltf::Material>& materials,
const std::vector<fastgltf::Texture>& textures,
const std::vector<std::optional<Image>>& images,
MeshRenderer& meshRenderer) {
Logger::debug("[GltfLoad] Loading " + std::to_string(materials.size()) + " material(s)...");

meshRenderer.getMaterials().clear();
Expand All @@ -343,25 +364,28 @@ void loadMaterials(const std::vector<fastgltf::Material>& materials, const std::
matProgram.setAttribute(mat.pbrData.metallicFactor, MaterialAttribute::Metallic);
matProgram.setAttribute(mat.pbrData.roughnessFactor, MaterialAttribute::Roughness);

if (mat.pbrData.baseColorTexture && images[mat.pbrData.baseColorTexture->textureIndex])
matProgram.setTexture(Texture2D::create(*images[mat.pbrData.baseColorTexture->textureIndex]), MaterialTexture::BaseColor);
loadTexture(mat.pbrData.baseColorTexture, textures, images, [&matProgram] (const Image& img) {
matProgram.setTexture(Texture2D::create(img), MaterialTexture::BaseColor);
});

if (mat.emissiveTexture && images[mat.emissiveTexture->textureIndex])
matProgram.setTexture(Texture2D::create(*images[mat.emissiveTexture->textureIndex]), MaterialTexture::Emissive);
loadTexture(mat.emissiveTexture, textures, images, [&matProgram] (const Image& img) {
matProgram.setTexture(Texture2D::create(img), MaterialTexture::Emissive);
});

if (mat.occlusionTexture && images[mat.occlusionTexture->textureIndex]) { // Ambient occlusion
const Image ambientOcclusionImg = extractAmbientOcclusionImage(*images[mat.occlusionTexture->textureIndex]);
loadTexture(mat.occlusionTexture, textures, images, [&matProgram] (const Image& img) {
const Image ambientOcclusionImg = extractAmbientOcclusionImage(img);
matProgram.setTexture(Texture2D::create(ambientOcclusionImg), MaterialTexture::Ambient);
}
});

if (mat.normalTexture && images[mat.normalTexture->textureIndex])
matProgram.setTexture(Texture2D::create(*images[mat.normalTexture->textureIndex]), MaterialTexture::Normal);
loadTexture(mat.normalTexture, textures, images, [&matProgram] (const Image& img) {
matProgram.setTexture(Texture2D::create(img), MaterialTexture::Normal);
});

if (mat.pbrData.metallicRoughnessTexture && images[mat.pbrData.metallicRoughnessTexture->textureIndex]) {
const auto [metalnessImg, roughnessImg] = extractMetalnessRoughnessImages(*images[mat.pbrData.metallicRoughnessTexture->textureIndex]);
loadTexture(mat.pbrData.metallicRoughnessTexture, textures, images, [&matProgram] (const Image& img) {
const auto [metalnessImg, roughnessImg] = extractMetalnessRoughnessImages(img);
matProgram.setTexture(Texture2D::create(metalnessImg), MaterialTexture::Metallic);
matProgram.setTexture(Texture2D::create(roughnessImg), MaterialTexture::Roughness);
}
});

loadedMat.loadType(MaterialType::COOK_TORRANCE);
}
Expand Down Expand Up @@ -407,7 +431,7 @@ std::pair<Mesh, MeshRenderer> load(const FilePath& filePath) {
auto [mesh, meshRenderer] = loadMeshes(asset->meshes, asset->buffers, asset->bufferViews, asset->accessors, transforms);

const std::vector<std::optional<Image>> images = loadImages(asset->images, asset->buffers, asset->bufferViews, parentPath);
loadMaterials(asset->materials, images, meshRenderer);
loadMaterials(asset->materials, asset->textures, images, meshRenderer);

Logger::debug("[GltfLoad] Loaded glTF file (" + std::to_string(mesh.getSubmeshes().size()) + " submesh(es), "
+ std::to_string(mesh.recoverVertexCount()) + " vertices, "
Expand Down
2 changes: 1 addition & 1 deletion src/RaZ/Render/ShaderProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void ShaderProgram::setImageTexture(TexturePtr texture, const std::string& unifo
throw std::runtime_error("Error: Using image textures requires OpenGL 4.2+ or OpenGL ES 3.1+");
}

if (texture->getColorspace() == Raz::TextureColorspace::INVALID || texture->getColorspace() == Raz::TextureColorspace::DEPTH)
if (texture->getColorspace() == TextureColorspace::INVALID || texture->getColorspace() == TextureColorspace::DEPTH)
throw std::invalid_argument("Error: The given image texture's colorspace is invalid");

auto imgTextureIt = std::find_if(m_imageTextures.begin(), m_imageTextures.end(), [&uniformName] (const auto& element) {
Expand Down
16 changes: 8 additions & 8 deletions tests/assets/meshes/çûbè.gltf
Original file line number Diff line number Diff line change
Expand Up @@ -146,27 +146,27 @@
0.99
],
"baseColorTexture": {
"index": 0
"index": 2
},
"metallicFactor": 0.5,
"roughnessFactor": 0.25,
"metallicRoughnessTexture": {
"index": 0
"index": 2
}
},
"normalTexture": {
"index": 2
"index": 1
},
"occlusionTexture": {
"index": 0
"index": 2
},
"emissiveFactor": [
0.75,
0.75,
0.75
],
"emissiveTexture": {
"index": 1
"index": 0
}
}
],
Expand Down Expand Up @@ -302,15 +302,15 @@
"textures": [
{
"sampler": 0,
"source": 0
"source": 1
},
{
"sampler": 0,
"source": 1
"source": 2
},
{
"sampler": 0,
"source": 2
"source": 0
}
]
}

0 comments on commit db53b4a

Please sign in to comment.