From 1bd123281be1814455b09b282c8f85a8fab727f8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 23 Nov 2024 07:56:46 +0900 Subject: [PATCH 1/2] extern: Update cgltf with KHR_materials_diffuse_transmission support See https://github.com/jkuhlmann/cgltf/pull/179 --- extern/cgltf.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/extern/cgltf.h b/extern/cgltf.h index 36fd644e1..6fb3178d1 100644 --- a/extern/cgltf.h +++ b/extern/cgltf.h @@ -500,6 +500,14 @@ typedef struct cgltf_iridescence cgltf_texture_view iridescence_thickness_texture; } cgltf_iridescence; +typedef struct cgltf_diffuse_transmission +{ + cgltf_texture_view diffuse_transmission_texture; + cgltf_float diffuse_transmission_factor; + cgltf_float diffuse_transmission_color_factor[3]; + cgltf_texture_view diffuse_transmission_color_texture; +} cgltf_diffuse_transmission; + typedef struct cgltf_anisotropy { cgltf_float anisotropy_strength; @@ -525,6 +533,7 @@ typedef struct cgltf_material cgltf_bool has_sheen; cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; + cgltf_bool has_diffuse_transmission; cgltf_bool has_anisotropy; cgltf_bool has_dispersion; cgltf_pbr_metallic_roughness pbr_metallic_roughness; @@ -537,6 +546,7 @@ typedef struct cgltf_material cgltf_volume volume; cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; + cgltf_diffuse_transmission diffuse_transmission; cgltf_anisotropy anisotropy; cgltf_dispersion dispersion; cgltf_texture_view normal_texture; @@ -4278,6 +4288,51 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const* return i; } +static int cgltf_parse_json_diffuse_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_diffuse_transmission* out_diff_transmission) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + // Defaults + cgltf_fill_float_array(out_diff_transmission->diffuse_transmission_color_factor, 3, 1.0f); + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionFactor") == 0) + { + ++i; + out_diff_transmission->diffuse_transmission_factor = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_texture); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorFactor") == 0) + { + i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_diff_transmission->diffuse_transmission_color_factor, 3); + } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorTexture") == 0) + { + i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_color_texture); + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -4766,6 +4821,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_iridescence = 1; i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_diffuse_transmission") == 0) + { + out_material->has_diffuse_transmission = 1; + i = cgltf_parse_json_diffuse_transmission(options, tokens, i + 1, json_chunk, &out_material->diffuse_transmission); + } else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0) { out_material->has_anisotropy = 1; @@ -6629,6 +6689,9 @@ static int cgltf_fixup_pointers(cgltf_data* data) CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count); CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_color_texture.texture, data->textures, data->textures_count); + CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count); } From c98251f83a38442f7097753b29177a1349d17646 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 23 Nov 2024 07:58:46 +0900 Subject: [PATCH 2/2] gltfpack: Implement support for KHR_materials_diffuse_transmission Specification: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_diffuse_transmission/README.md --- gltf/README.md | 1 + gltf/gltfpack.cpp | 3 +++ gltf/material.cpp | 29 +++++++++++++++++++++++++++++ gltf/write.cpp | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/gltf/README.md b/gltf/README.md index 4b278676a..aed8042f1 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -69,6 +69,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th - KHR_lights_punctual - KHR_materials_anisotropy - KHR_materials_clearcoat +- KHR_materials_diffuse_transmission - KHR_materials_dispersion - KHR_materials_emissive_strength - KHR_materials_ior diff --git a/gltf/gltfpack.cpp b/gltf/gltfpack.cpp index a61f057c9..31327ac55 100644 --- a/gltf/gltfpack.cpp +++ b/gltf/gltfpack.cpp @@ -480,6 +480,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output bool ext_iridescence = false; bool ext_anisotropy = false; bool ext_dispersion = false; + bool ext_diffuse_transmission = false; bool ext_unlit = false; bool ext_instancing = false; bool ext_texture_transform = false; @@ -574,6 +575,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output ext_volume = ext_volume || material.has_volume; ext_emissive_strength = ext_emissive_strength || material.has_emissive_strength; ext_iridescence = ext_iridescence || material.has_iridescence; + ext_diffuse_transmission = ext_diffuse_transmission || material.has_diffuse_transmission; ext_anisotropy = ext_anisotropy || material.has_anisotropy; ext_dispersion = ext_dispersion || material.has_dispersion; ext_unlit = ext_unlit || material.unlit; @@ -856,6 +858,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output {"KHR_materials_iridescence", ext_iridescence, false}, {"KHR_materials_anisotropy", ext_anisotropy, false}, {"KHR_materials_dispersion", ext_dispersion, false}, + {"KHR_materials_diffuse_transmission", ext_diffuse_transmission, false}, {"KHR_materials_unlit", ext_unlit, false}, {"KHR_materials_variants", data->variants_count > 0, false}, {"KHR_lights_punctual", data->lights_count > 0, false}, diff --git a/gltf/material.cpp b/gltf/material.cpp index 68d5610c8..ff52397c4 100644 --- a/gltf/material.cpp +++ b/gltf/material.cpp @@ -246,6 +246,23 @@ static bool areMaterialComponentsEqual(const cgltf_dispersion& lhs, const cgltf_ return true; } +static bool areMaterialComponentsEqual(const cgltf_diffuse_transmission& lhs, const cgltf_diffuse_transmission& rhs) +{ + if (lhs.diffuse_transmission_factor != rhs.diffuse_transmission_factor) + return false; + + if (memcmp(lhs.diffuse_transmission_color_factor, rhs.diffuse_transmission_color_factor, sizeof(cgltf_float) * 3) != 0) + return false; + + if (!areTextureViewsEqual(lhs.diffuse_transmission_texture, rhs.diffuse_transmission_texture)) + return false; + + if (!areTextureViewsEqual(lhs.diffuse_transmission_color_texture, rhs.diffuse_transmission_color_texture)) + return false; + + return true; +} + static bool areMaterialsEqual(const cgltf_material& lhs, const cgltf_material& rhs, const Settings& settings) { if (lhs.has_pbr_metallic_roughness != rhs.has_pbr_metallic_roughness) @@ -320,6 +337,12 @@ static bool areMaterialsEqual(const cgltf_material& lhs, const cgltf_material& r if (lhs.has_dispersion && !areMaterialComponentsEqual(lhs.dispersion, rhs.dispersion)) return false; + if (lhs.has_diffuse_transmission != rhs.has_diffuse_transmission) + return false; + + if (lhs.has_diffuse_transmission && !areMaterialComponentsEqual(lhs.diffuse_transmission, rhs.diffuse_transmission)) + return false; + if (!areTextureViewsEqual(lhs.normal_texture, rhs.normal_texture)) return false; @@ -535,6 +558,12 @@ static void analyzeMaterial(const cgltf_material& material, MaterialInfo& mi, cg analyzeMaterialTexture(material.anisotropy.anisotropy_texture, TextureKind_Normal, mi, data, textures, images); } + if (material.has_diffuse_transmission) + { + analyzeMaterialTexture(material.diffuse_transmission.diffuse_transmission_texture, TextureKind_Attrib, mi, data, textures, images); + analyzeMaterialTexture(material.diffuse_transmission.diffuse_transmission_color_texture, TextureKind_Color, mi, data, textures, images); + } + analyzeMaterialTexture(material.normal_texture, TextureKind_Normal, mi, data, textures, images); analyzeMaterialTexture(material.occlusion_texture, TextureKind_Attrib, mi, data, textures, images); analyzeMaterialTexture(material.emissive_texture, TextureKind_Color, mi, data, textures, images); diff --git a/gltf/write.cpp b/gltf/write.cpp index e76591ebf..2536b4d18 100644 --- a/gltf/write.cpp +++ b/gltf/write.cpp @@ -550,6 +550,37 @@ static void writeMaterialComponent(std::string& json, const cgltf_data* data, co append(json, "}"); } +static void writeMaterialComponent(std::string& json, const cgltf_data* data, const cgltf_diffuse_transmission& tm, const QuantizationTexture* qt, std::vector& textures) +{ + comma(json); + append(json, "\"KHR_materials_diffuse_transmission\":{"); + if (tm.diffuse_transmission_factor != 0) + { + comma(json); + append(json, "\"diffuseTransmissionFactor\":"); + append(json, tm.diffuse_transmission_factor); + } + if (tm.diffuse_transmission_texture.texture) + { + comma(json); + append(json, "\"diffuseTransmissionTexture\":"); + writeTextureInfo(json, data, tm.diffuse_transmission_texture, qt, textures); + } + if (memcmp(tm.diffuse_transmission_color_factor, white, sizeof(float) * 3) != 0) + { + comma(json); + append(json, "\"diffuseTransmissionColorFactor\":"); + append(json, tm.diffuse_transmission_color_factor, 3); + } + if (tm.diffuse_transmission_color_texture.texture) + { + comma(json); + append(json, "\"diffuseTransmissionColorTexture\":"); + writeTextureInfo(json, data, tm.diffuse_transmission_color_texture, qt, textures); + } + append(json, "}"); +} + void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_material& material, const QuantizationPosition* qp, const QuantizationTexture* qt, std::vector& textures) { if (material.name && *material.name) @@ -614,7 +645,9 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi append(json, "\"doubleSided\":true"); } - if (material.has_pbr_specular_glossiness || material.has_clearcoat || material.has_transmission || material.has_ior || material.has_specular || material.has_sheen || material.has_volume || material.has_emissive_strength || material.has_iridescence || material.has_anisotropy || material.has_dispersion || material.unlit) + if (material.has_pbr_specular_glossiness || material.has_clearcoat || material.has_transmission || material.has_ior || material.has_specular || + material.has_sheen || material.has_volume || material.has_emissive_strength || material.has_iridescence || material.has_anisotropy || + material.has_dispersion || material.has_diffuse_transmission || material.unlit) { comma(json); append(json, "\"extensions\":{"); @@ -652,6 +685,9 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi if (material.has_dispersion) writeMaterialComponent(json, data, material.dispersion); + if (material.has_diffuse_transmission) + writeMaterialComponent(json, data, material.diffuse_transmission, qt, textures); + if (material.unlit) { comma(json);