Now parsing all material parameters from GLTF
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

Add missing clearcoatMap scale.
This commit is contained in:
2026-05-04 23:02:05 -07:00
parent ed036caec5
commit bd63e1291d
3 changed files with 129 additions and 26 deletions

View File

@@ -176,7 +176,13 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
simdjson::ondemand::array jsonMaterials; simdjson::ondemand::array jsonMaterials;
if (tryJson(jsonRoot["materials"].get_array().get(jsonMaterials))) { if (tryJson(jsonRoot["materials"].get_array().get(jsonMaterials))) {
int materialIndex = 0; int materialIndex = 0;
for (auto jsonMaterial : jsonMaterials) { for (auto jsonMaybeMaterial : jsonMaterials) {
KRMaterial*& new_material = materials.emplace_back();
new_material = nullptr;
simdjson::ondemand::object jsonMaterial;
if(!tryJsonRequired(jsonMaybeMaterial.get(jsonMaterial))) {
continue;
}
std::string materialName; std::string materialName;
std::string_view materialNameVal; std::string_view materialNameVal;
if (tryJson(jsonMaterial["name"].get(materialNameVal))) { if (tryJson(jsonMaterial["name"].get(materialNameVal))) {
@@ -186,34 +192,123 @@ KRBundle* LoadGltf(KRContext& context, simdjson::ondemand::object& jsonRoot, std
materialName = std::format("{}_material_{}", baseName, materialIndex); materialName = std::format("{}_material_{}", baseName, materialIndex);
} }
KRMaterial* new_material = new KRMaterial(context, std::string(materialName).c_str()); auto parseTextureInfoAttributes = [&materialName, &textures](simdjson::ondemand::object jsonTextureInfo, KRMaterial::TextureMap& textureMap)
{
tryJson(jsonTextureInfo["texCoord"].get(textureMap.texCoord));
int textureIndex = -1;
if(tryJson(jsonTextureInfo["index"].get(textureIndex))) {
if (textureIndex < 0 || textureIndex >= textures.size()) {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Material textureInfo with index out of bounds: %s", materialName.c_str());
} else {
const TextureInfo& texture = textures[textureIndex];
textureMap.scale = texture.scale;
textureMap.offset = texture.offset;
textureMap.rotation = texture.rotation;
textureMap.texture.set(texture.texture);
}
}
};
auto parseTextureInfo = [parseTextureInfoAttributes, &materialName, &textures](simdjson::ondemand::object jsonObj, const char* nodeName, KRMaterial::TextureMap& textureMap)
{
simdjson::ondemand::object jsonTextureInfo;
if(tryJson(jsonObj[nodeName].get(jsonTextureInfo))) {
parseTextureInfoAttributes(jsonTextureInfo, textureMap);
}
};
auto parseNormalTextureInfo = [parseTextureInfoAttributes, &materialName, &textures](simdjson::ondemand::object jsonObj, const char* nodeName, KRMaterial::TextureMap& textureMap, float* normalScale)
{
simdjson::ondemand::object jsonTextureInfo;
if(tryJson(jsonObj[nodeName].get(jsonTextureInfo))) {
parseTextureInfoAttributes(jsonTextureInfo, textureMap);
tryJson(jsonTextureInfo["scale"].get(*normalScale));
}
};
new_material = new KRMaterial(context, std::string(materialName).c_str());
simdjson::ondemand::object pbrMetallicRoughnessObj; simdjson::ondemand::object pbrMetallicRoughnessObj;
if(tryJson(jsonMaterial["pbrMetallicRoughness"].get(pbrMetallicRoughnessObj))) { if(tryJson(jsonMaterial["pbrMetallicRoughness"].get(pbrMetallicRoughnessObj))) {
tryJson(pbrMetallicRoughnessObj["baseColorFactor"].get(new_material->m_baseColorFactor)); tryJson(pbrMetallicRoughnessObj["baseColorFactor"].get(new_material->m_baseColorFactor));
simdjson::ondemand::object baseColorTextureInfo; parseTextureInfo(pbrMetallicRoughnessObj, "baseColorTexture", new_material->m_baseColorMap);
if(tryJson(pbrMetallicRoughnessObj["baseColorTexture"].get(baseColorTextureInfo))) {
tryJson(baseColorTextureInfo["texCoord"].get(new_material->m_baseColorMap.texCoord));
int textureIndex = -1;
if(tryJson(baseColorTextureInfo["index"].get(textureIndex))) {
if (textureIndex < 0 || textureIndex >= textures.size()) {
// TODO: Log error...
} else {
const TextureInfo& texture = textures[textureIndex];
new_material->m_baseColorMap.scale = texture.scale;
new_material->m_baseColorMap.offset = texture.offset;
new_material->m_baseColorMap.rotation = texture.rotation;
new_material->m_baseColorMap.texture.set(texture.texture);
}
}
} // baseColorTexture
// baseColorTexture...
tryJson(pbrMetallicRoughnessObj["metallicFactor"].get(new_material->m_metalicFactor)); tryJson(pbrMetallicRoughnessObj["metallicFactor"].get(new_material->m_metalicFactor));
tryJson(pbrMetallicRoughnessObj["roughnessFactor"].get(new_material->m_roughnessFactor)); tryJson(pbrMetallicRoughnessObj["roughnessFactor"].get(new_material->m_roughnessFactor));
// metallicRoughnessTexture... parseTextureInfo(pbrMetallicRoughnessObj, "metallicRoughnessTexture", new_material->m_metalicRoughnessMap);
} }
parseNormalTextureInfo(jsonMaterial, "normalTexture", new_material->m_normalMap, &new_material->m_normalScale);
simdjson::ondemand::object occlusionTextureInfo;
if(tryJson(jsonMaterial["occlusionTexture"].get(occlusionTextureInfo))) {
parseTextureInfoAttributes(occlusionTextureInfo, new_material->m_occlusionMap);
tryJson(occlusionTextureInfo["strength"].get(new_material->m_occlusionStrength));
}
parseTextureInfo(jsonMaterial, "emissiveTexture", new_material->m_emissiveMap);
tryJson(jsonMaterial["emissiveFactor"].get(new_material->m_emissiveFactor));
new_material->moveToBundle(bundle); new_material->moveToBundle(bundle);
materials.push_back(new_material);
std::string_view alphaMode;
if(tryJson(jsonMaterial["alphaMode"].get(alphaMode))) {
if (alphaMode.compare("OPAQUE") == 0) {
new_material->m_alphaMode = KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE;
} else if (alphaMode.compare("BLEND") == 0) {
new_material->m_alphaMode = KRMaterial::KRMATERIAL_ALPHA_MODE_BLEND;
} else if (alphaMode.compare("MASK") == 0) {
new_material->m_alphaMode = KRMaterial::KRMATERIAL_ALPHA_MODE_TEST;
} else {
KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Kraken - GLTF: Material with unknown alphaMode: %s", materialName.c_str());
}
}
tryJson(jsonMaterial["alphaCutoff"].get(new_material->m_alphaCutoff));
tryJson(jsonMaterial["doubleSided"].get(new_material->m_doubleSided));
simdjson::ondemand::object extensions;
if(tryJson(jsonMaterial["extensions"].get(extensions))) {
tryJson(extensions["KHR_materials_ior"]["ior"].get(new_material->m_ior));
tryJson(extensions["KHR_materials_dispersion"]["dispersino"].get(new_material->m_dispersion));
simdjson::ondemand::object extensions_KHR_materials_unlit;
if(tryJson(extensions["KHR_materials_unlit"].get(extensions_KHR_materials_unlit))) {
// The presence of the KHR_materials_unlit node is all that is needed to enable the unlit shading model
new_material->m_shadingModel = KRMaterial::KRMATERIAL_SHADING_MODEL_UNLIT;
} else {
new_material->m_shadingModel = KRMaterial::KRMATERIAL_SHADING_MODEL_PBR;
}
simdjson::ondemand::object extensions_KHR_materials_anisotropy;
if(tryJson(extensions["KHR_materials_anisotropy"].get(extensions_KHR_materials_anisotropy))) {
parseTextureInfo(extensions_KHR_materials_anisotropy, "anisotropyTexture", new_material->m_anisotropyMap);
tryJson(extensions_KHR_materials_anisotropy["anisotropyStrength"].get(new_material->m_anisotropyStrength));
tryJson(extensions_KHR_materials_anisotropy["anisotropyRotation"].get(new_material->m_anisotropyRotation));
}
simdjson::ondemand::object extensions_KHR_materials_clearcoat;
if(tryJson(extensions["KHR_materials_clearcoat"].get(extensions_KHR_materials_clearcoat))) {
tryJson(extensions_KHR_materials_clearcoat["clearcoatFactor"].get(new_material->m_clearcoatFactor));
parseTextureInfo(extensions_KHR_materials_clearcoat, "clearcoatTexture", new_material->m_clearcoatMap);
tryJson(extensions_KHR_materials_clearcoat["clearcoatRoughnessFactor"].get(new_material->m_clearcoatRoughnessFactor));
parseTextureInfo(extensions_KHR_materials_clearcoat, "clearcoatRoughnessTexture", new_material->m_clearcoatRoughnessMap);
parseNormalTextureInfo(extensions_KHR_materials_clearcoat, "clearcoatNormalTexture", new_material->m_clearcoatNormalMap, &new_material->m_clearcoatNormalScale);
}
simdjson::ondemand::object extensions_KHR_materials_specular;
if(tryJson(extensions["KHR_materials_specular"].get(extensions_KHR_materials_specular))) {
tryJson(extensions_KHR_materials_specular["specularFactor"].get(new_material->m_specularFactor));
parseTextureInfo(extensions_KHR_materials_specular, "specularTexture", new_material->m_specularMap);
tryJson(extensions_KHR_materials_specular["specularColorFactor"].get(new_material->m_specularColorFactor));
parseTextureInfo(extensions_KHR_materials_specular, "specularColorTexture", new_material->m_specularColorTexture);
}
simdjson::ondemand::object extensions_KHR_materials_volume;
if(tryJson(extensions["KHR_materials_volume"].get(extensions_KHR_materials_volume))) {
tryJson(extensions_KHR_materials_volume["thicknessFactor"].get(new_material->m_thicknessFactor));
parseTextureInfo(extensions_KHR_materials_volume, "thicknessTexture", new_material->m_thicknessMap);
tryJson(extensions_KHR_materials_volume["attenuationDistance"].get(new_material->m_attenuationDistance));
tryJson(extensions_KHR_materials_volume["attenuationColor"].get(new_material->m_attenuationColor));
}
simdjson::ondemand::object extensions_KHR_materials_transmission;
if(tryJson(extensions["KHR_materials_transmission"].get(extensions_KHR_materials_transmission))) {
tryJson(extensions_KHR_materials_transmission["transmissionFactor"].get(new_material->m_transmissionFactor));
parseTextureInfo(extensions_KHR_materials_transmission, "transmissionTexture", new_material->m_transmissionMap);
}
}
materialIndex++; materialIndex++;
} }
} }

View File

@@ -285,6 +285,13 @@ KRMaterial::KRMaterial(KRContext& context, std::string name, mimir::Block* data)
// TODO - Report and handle error // TODO - Report and handle error
} }
tryJson(clearcoatObj["roughnessFactor"].get(m_clearcoatRoughnessFactor)); tryJson(clearcoatObj["roughnessFactor"].get(m_clearcoatRoughnessFactor));
error = clearcoatObj["normalMap"].get(mapVal);
if (error == simdjson::SUCCESS) {
tryJson(m_clearcoatNormalMap.parse(mapVal));
} else if (error != simdjson::EMPTY) {
// TODO - Report and handle error
}
tryJson(clearcoatObj["clearcoatNormalScale"].get(m_clearcoatNormalScale));
} else if (error != simdjson::EMPTY) { } else if (error != simdjson::EMPTY) {
// TODO - Report and handle error // TODO - Report and handle error
} }
@@ -484,6 +491,10 @@ bool KRMaterial::save(Block& data)
sb.append_key_value<"roughnessMap">(m_clearcoatRoughnessMap); sb.append_key_value<"roughnessMap">(m_clearcoatRoughnessMap);
sb.append_comma(); sb.append_comma();
sb.append_key_value<"roughnessFactor">(m_clearcoatRoughnessFactor); sb.append_key_value<"roughnessFactor">(m_clearcoatRoughnessFactor);
sb.append_comma();
sb.append_key_value<"normalMap">(m_clearcoatNormalMap);
sb.append_comma();
sb.append_key_value<"normalScale">(m_clearcoatNormalScale);
sb.end_object(); sb.end_object();
sb.append_comma(); sb.append_comma();
@@ -682,10 +693,6 @@ kraken_stream_level KRMaterial::getStreamLevel()
stream_level = KRMIN(stream_level, m_clearcoatMap.texture.get()->getStreamLevel()); stream_level = KRMIN(stream_level, m_clearcoatMap.texture.get()->getStreamLevel());
} }
if (m_clearcoatMap.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatMap.texture.get()->getStreamLevel());
}
if (m_clearcoatRoughnessMap.texture.isBound()) { if (m_clearcoatRoughnessMap.texture.isBound()) {
stream_level = KRMIN(stream_level, m_clearcoatRoughnessMap.texture.get()->getStreamLevel()); stream_level = KRMIN(stream_level, m_clearcoatRoughnessMap.texture.get()->getStreamLevel());
} }

View File

@@ -149,6 +149,7 @@ public:
TextureMap m_clearcoatRoughnessMap{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_ROUGHNESS }; TextureMap m_clearcoatRoughnessMap{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_ROUGHNESS };
float m_clearcoatRoughnessFactor{ 0.f }; float m_clearcoatRoughnessFactor{ 0.f };
TextureMap m_clearcoatNormalMap{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_NORMAL }; TextureMap m_clearcoatNormalMap{ KRTexture::TEXTURE_USAGE_MATERIAL_CLEARCOAT_NORMAL };
float m_clearcoatNormalScale{ 1.f };
float m_dispersion{ 0.f }; float m_dispersion{ 0.f };