diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-12-02 22:33:19 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-12-02 22:33:19 +0000 |
| commit | 58410367ebd4e0ea110527cb2ed42f8c6dc79b40 (patch) | |
| tree | 314f81089f76f2847dae332ca0992b01bf568b7d /AssetLoader | |
| parent | GLTF Loader: fixed few issues with texture cache (diff) | |
| download | DiligentTools-58410367ebd4e0ea110527cb2ed42f8c6dc79b40.tar.gz DiligentTools-58410367ebd4e0ea110527cb2ed42f8c6dc79b40.zip | |
GLTFLoader: reworked material to load material attribs in a shader-friendly format
Diffstat (limited to 'AssetLoader')
| -rw-r--r-- | AssetLoader/interface/GLTFLoader.hpp | 100 | ||||
| -rw-r--r-- | AssetLoader/src/GLTFLoader.cpp | 64 |
2 files changed, 89 insertions, 75 deletions
diff --git a/AssetLoader/interface/GLTFLoader.hpp b/AssetLoader/interface/GLTFLoader.hpp index 2575898..f378e46 100644 --- a/AssetLoader/interface/GLTFLoader.hpp +++ b/AssetLoader/interface/GLTFLoader.hpp @@ -65,7 +65,49 @@ struct GLTFCacheInfo struct Material { - Material() noexcept {} + Material() noexcept + { + TextureIds.fill(-1); + } + + enum PBR_WORKFLOW + { + PBR_WORKFLOW_METALL_ROUGH = 0, + PBR_WORKFLOW_SPEC_GLOSS + }; + + // Material attributes packed in a shader-friendly format + struct ShaderAttribs + { + float4 BaseColorFactor = float4{1, 1, 1, 1}; + float4 EmissiveFactor = float4{1, 1, 1, 1}; + float4 SpecularFactor = float4{1, 1, 1, 1}; + + int Workflow = PBR_WORKFLOW_METALL_ROUGH; + float BaseColorUVSelector = -1; + float PhysicalDescriptorUVSelector = -1; + float NormalUVSelector = -1; + + float OcclusionUVSelector = -1; + float EmissiveUVSelector = -1; + float MetallicFactor = 1; + float RoughnessFactor = 1; + + // When texture atlas is used, UV scale and bias applied to + // each texture coordinate set + float4 BaseColorUVScaleBias = float4{1, 1, 0, 0}; + float4 PhysicalDescriptorUVScaleBias = float4{1, 1, 0, 0}; + float4 NormalUVScaleBias = float4{1, 1, 0, 0}; + float4 OcclusionUVScaleBias = float4{1, 1, 0, 0}; + float4 EmissiveUVScaleBias = float4{1, 1, 0, 0}; + + int UseAlphaMask = 0; + float AlphaCutoff = 0.5f; + float Dummy0; + float Dummy1; + }; + static_assert(sizeof(ShaderAttribs) % 16 == 0, "ShaderAttribs struct must be 16-byte aligned"); + ShaderAttribs Attribs; enum ALPHA_MODE { @@ -77,62 +119,22 @@ struct Material bool DoubleSided = false; - float AlphaCutoff = 1.0f; - float MetallicFactor = 1.0f; - float RoughnessFactor = 1.0f; - - float4 BaseColorFactor = float4{1, 1, 1, 1}; - float4 EmissiveFactor = float4{1, 1, 1, 1}; - float4 DiffuseFactor = float4{1, 1, 1, 1}; - float4 SpecularFactor = float4{1, 1, 1, 1}; - - struct TextureAttribs - { - // Texture index in Model.Textures array - Int16 Index = -1; - - // Texture coordinates set (UV0 / UV1) - Uint8 CoordSet = 0; - - void SetIndex(int Idx) - { - // clang-format off - DEV_CHECK_ERR(Idx >= static_cast<int>(std::numeric_limits<decltype(Index)>::min()) && - Idx <= static_cast<int>(std::numeric_limits<decltype(Index)>::max()), - "Texture index (", Idx, ") is out of representable range"); - // clang-format on - Index = static_cast<decltype(Index)>(Idx); - } - - void SetCoordSet(int Set) - { - // clang-format off - DEV_CHECK_ERR(Set >= static_cast<int>(std::numeric_limits<decltype(CoordSet)>::min()) && - Set <= static_cast<int>(std::numeric_limits<decltype(CoordSet)>::max()), - "Texture coordinate set (", Set, ") is out of representable range"); - // clang-format on - CoordSet = static_cast<decltype(CoordSet)>(Set); - } - }; enum TEXTURE_ID { + // Base color for metallic-roughness workflow or + // diffuse color for specular-glossinees workflow TEXTURE_ID_BASE_COLOR = 0, - TEXTURE_ID_METALL_ROUGHNESS, + + // Metallic-roughness or specular-glossinees map + TEXTURE_ID_PHYSICAL_DESC, + TEXTURE_ID_NORMAL_MAP, TEXTURE_ID_OCCLUSION, TEXTURE_ID_EMISSIVE, - TEXTURE_ID_SPEC_GLOSS, - TEXTURE_ID_DIFFUSE, TEXTURE_ID_NUM_TEXTURES }; - std::array<TextureAttribs, TEXTURE_ID_NUM_TEXTURES> Textures; - - enum class PbrWorkflow - { - MetallicRoughness, - SpecularGlossiness - }; - PbrWorkflow workflow = PbrWorkflow::MetallicRoughness; + // Texture indices in Model.Textures array + std::array<int, TEXTURE_ID_NUM_TEXTURES> TextureIds = {}; }; diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp index 7d5b75a..c6618f6 100644 --- a/AssetLoader/src/GLTFLoader.cpp +++ b/AssetLoader/src/GLTFLoader.cpp @@ -1004,17 +1004,19 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) struct TextureParameterInfo { const Material::TEXTURE_ID TextureId; + float& UVSelector; + float4& UVScaleBias; const char* const TextureName; const tinygltf::ParameterMap& Params; }; // clang-format off std::array<TextureParameterInfo, 5> TextureParams = { - TextureParameterInfo{Material::TEXTURE_ID_BASE_COLOR, "baseColorTexture", gltf_mat.values}, - TextureParameterInfo{Material::TEXTURE_ID_METALL_ROUGHNESS, "metallicRoughnessTexture", gltf_mat.values}, - TextureParameterInfo{Material::TEXTURE_ID_NORMAL_MAP, "normalTexture", gltf_mat.additionalValues}, - TextureParameterInfo{Material::TEXTURE_ID_OCCLUSION, "occlusionTexture", gltf_mat.additionalValues}, - TextureParameterInfo{Material::TEXTURE_ID_EMISSIVE, "emissiveTexture", gltf_mat.additionalValues} + TextureParameterInfo{Material::TEXTURE_ID_BASE_COLOR, Mat.Attribs.BaseColorUVSelector, Mat.Attribs.BaseColorUVScaleBias, "baseColorTexture", gltf_mat.values}, + TextureParameterInfo{Material::TEXTURE_ID_PHYSICAL_DESC, Mat.Attribs.PhysicalDescriptorUVSelector, Mat.Attribs.PhysicalDescriptorUVScaleBias, "metallicRoughnessTexture", gltf_mat.values}, + TextureParameterInfo{Material::TEXTURE_ID_NORMAL_MAP, Mat.Attribs.NormalUVSelector, Mat.Attribs.NormalUVScaleBias, "normalTexture", gltf_mat.additionalValues}, + TextureParameterInfo{Material::TEXTURE_ID_OCCLUSION, Mat.Attribs.OcclusionUVSelector, Mat.Attribs.OcclusionUVScaleBias, "occlusionTexture", gltf_mat.additionalValues}, + TextureParameterInfo{Material::TEXTURE_ID_EMISSIVE, Mat.Attribs.EmissiveUVSelector, Mat.Attribs.EmissiveUVScaleBias, "emissiveTexture", gltf_mat.additionalValues} }; // clang-format on @@ -1023,9 +1025,8 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto tex_it = Param.Params.find(Param.TextureName); if (tex_it != Param.Params.end()) { - auto& TexInfo = Mat.Textures[Param.TextureId]; - TexInfo.SetIndex(tex_it->second.TextureIndex()); - TexInfo.SetCoordSet(tex_it->second.TextureTexCoord()); + Mat.TextureIds[Param.TextureId] = tex_it->second.TextureIndex(); + Param.UVSelector = static_cast<float>(tex_it->second.TextureTexCoord()); } } @@ -1037,8 +1038,8 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) Factor = static_cast<float>(it->second.Factor()); } }; - ReadFactor(Mat.RoughnessFactor, gltf_mat.values, "roughnessFactor"); - ReadFactor(Mat.MetallicFactor, gltf_mat.values, "metallicFactor"); + ReadFactor(Mat.Attribs.RoughnessFactor, gltf_mat.values, "roughnessFactor"); + ReadFactor(Mat.Attribs.MetallicFactor, gltf_mat.values, "metallicFactor"); auto ReadColorFactor = [](float4& Factor, const tinygltf::ParameterMap& Params, const char* Name) // { @@ -1049,8 +1050,8 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) } }; - ReadColorFactor(Mat.BaseColorFactor, gltf_mat.values, "baseColorFactor"); - ReadColorFactor(Mat.EmissiveFactor, gltf_mat.additionalValues, "emissiveFactor"); + ReadColorFactor(Mat.Attribs.BaseColorFactor, gltf_mat.values, "baseColorFactor"); + ReadColorFactor(Mat.Attribs.EmissiveFactor, gltf_mat.additionalValues, "emissiveFactor"); { auto alpha_mode_it = gltf_mat.additionalValues.find("alphaMode"); @@ -1063,13 +1064,15 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) } if (param.string_value == "MASK") { - Mat.AlphaCutoff = 0.5f; - Mat.AlphaMode = Material::ALPHAMODE_MASK; + Mat.AlphaMode = Material::ALPHAMODE_MASK; + + Mat.Attribs.UseAlphaMask = 1; + Mat.Attribs.AlphaCutoff = 0.5f; } } } - ReadFactor(Mat.AlphaCutoff, gltf_mat.additionalValues, "alphaCutoff"); + ReadFactor(Mat.Attribs.AlphaCutoff, gltf_mat.additionalValues, "alphaCutoff"); { auto double_sided_it = gltf_mat.additionalValues.find("doubleSided"); @@ -1079,6 +1082,8 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) } } + Mat.Attribs.Workflow = Material::PBR_WORKFLOW_METALL_ROUGH; + // Extensions // @TODO: Find out if there is a nicer way of reading these properties with recent tinygltf headers { @@ -1090,11 +1095,10 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto index = ext_it->second.Get("specularGlossinessTexture").Get("index"); auto texCoordSet = ext_it->second.Get("specularGlossinessTexture").Get("texCoord"); - auto& TexInfo = Mat.Textures[Material::TEXTURE_ID_SPEC_GLOSS]; - TexInfo.SetIndex(index.Get<int>()); - TexInfo.SetCoordSet(texCoordSet.Get<int>()); + Mat.TextureIds[Material::TEXTURE_ID_PHYSICAL_DESC] = index.Get<int>(); + Mat.Attribs.PhysicalDescriptorUVSelector = static_cast<float>(texCoordSet.Get<int>()); - Mat.workflow = Material::PbrWorkflow::SpecularGlossiness; + Mat.Attribs.Workflow = Material::PBR_WORKFLOW_SPEC_GLOSS; } if (ext_it->second.Has("diffuseTexture")) @@ -1102,9 +1106,8 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto index = ext_it->second.Get("diffuseTexture").Get("index"); auto texCoordSet = ext_it->second.Get("diffuseTexture").Get("texCoord"); - auto& TexInfo = Mat.Textures[Material::TEXTURE_ID_DIFFUSE]; - TexInfo.SetIndex(index.Get<int>()); - TexInfo.SetCoordSet(texCoordSet.Get<int>()); + Mat.TextureIds[Material::TEXTURE_ID_BASE_COLOR] = index.Get<int>(); + Mat.Attribs.BaseColorUVSelector = static_cast<float>(texCoordSet.Get<int>()); } if (ext_it->second.Has("diffuseFactor")) @@ -1112,8 +1115,9 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto factor = ext_it->second.Get("diffuseFactor"); for (uint32_t i = 0; i < factor.ArrayLen(); i++) { - const auto val = factor.Get(i); - Mat.DiffuseFactor[i] = val.IsNumber() ? (float)val.Get<double>() : (float)val.Get<int>(); + const auto val = factor.Get(i); + Mat.Attribs.BaseColorFactor[i] = + val.IsNumber() ? (float)val.Get<double>() : (float)val.Get<int>(); } } @@ -1122,13 +1126,21 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model) auto factor = ext_it->second.Get("specularFactor"); for (uint32_t i = 0; i < factor.ArrayLen(); i++) { - const auto val = factor.Get(i); - Mat.SpecularFactor[i] = val.IsNumber() ? (float)val.Get<double>() : (float)val.Get<int>(); + const auto val = factor.Get(i); + Mat.Attribs.SpecularFactor[i] = + val.IsNumber() ? (float)val.Get<double>() : (float)val.Get<int>(); } } } } + for (const auto& Param : TextureParams) + { + auto TexIndex = Mat.TextureIds[Param.TextureId]; + if (TexIndex >= 0) + Param.UVScaleBias = GetUVScaleBias(TexIndex); + } + Materials.push_back(Mat); } |
