Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gltfpack: Implement support for KHR_materials_diffuse_transmission #809

Merged
merged 2 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions extern/cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions gltf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions gltf/gltfpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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},
Expand Down
29 changes: 29 additions & 0 deletions gltf/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
38 changes: 37 additions & 1 deletion gltf/write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TextureInfo>& 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<TextureInfo>& textures)
{
if (material.name && *material.name)
Expand Down Expand Up @@ -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\":{");
Expand Down Expand Up @@ -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);
Expand Down