summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-12-02 22:33:19 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-12-02 22:33:19 +0000
commit58410367ebd4e0ea110527cb2ed42f8c6dc79b40 (patch)
tree314f81089f76f2847dae332ca0992b01bf568b7d
parentGLTF Loader: fixed few issues with texture cache (diff)
downloadDiligentTools-58410367ebd4e0ea110527cb2ed42f8c6dc79b40.tar.gz
DiligentTools-58410367ebd4e0ea110527cb2ed42f8c6dc79b40.zip
GLTFLoader: reworked material to load material attribs in a shader-friendly format
-rw-r--r--AssetLoader/interface/GLTFLoader.hpp100
-rw-r--r--AssetLoader/src/GLTFLoader.cpp64
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);
}