Skip to content

Commit 468ad38

Browse files
authored
Merge pull request #124 from romainguy/rg/KHR_materials_specular
Add support for KHR_materials_specular
2 parents 062695f + 2bf0b35 commit 468ad38

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ cgltf also supports some glTF extensions:
106106
- KHR_materials_clearcoat
107107
- KHR_materials_ior
108108
- KHR_materials_pbrSpecularGlossiness
109+
- KHR_materials_specular
109110
- KHR_materials_transmission
110111
- KHR_materials_unlit
111112
- KHR_texture_transform

cgltf.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,13 @@ typedef struct cgltf_ior
408408
cgltf_float ior;
409409
} cgltf_ior;
410410

411+
typedef struct cgltf_specular
412+
{
413+
cgltf_texture_view specular_texture;
414+
cgltf_float specular_color_factor[3];
415+
cgltf_float specular_factor;
416+
} cgltf_specular;
417+
411418
typedef struct cgltf_material
412419
{
413420
char* name;
@@ -416,10 +423,12 @@ typedef struct cgltf_material
416423
cgltf_bool has_clearcoat;
417424
cgltf_bool has_transmission;
418425
cgltf_bool has_ior;
426+
cgltf_bool has_specular;
419427
cgltf_pbr_metallic_roughness pbr_metallic_roughness;
420428
cgltf_pbr_specular_glossiness pbr_specular_glossiness;
421429
cgltf_clearcoat clearcoat;
422430
cgltf_ior ior;
431+
cgltf_specular specular;
423432
cgltf_transmission transmission;
424433
cgltf_texture_view normal_texture;
425434
cgltf_texture_view occlusion_texture;
@@ -1661,6 +1670,10 @@ void cgltf_free(cgltf_data* data)
16611670
cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions, data->materials[i].clearcoat.clearcoat_roughness_texture.extensions_count);
16621671
cgltf_free_extensions(data, data->materials[i].clearcoat.clearcoat_normal_texture.extensions, data->materials[i].clearcoat.clearcoat_normal_texture.extensions_count);
16631672
}
1673+
if(data->materials[i].has_specular)
1674+
{
1675+
cgltf_free_extensions(data, data->materials[i].specular.specular_texture.extensions, data->materials[i].specular.specular_texture.extensions_count);
1676+
}
16641677
if(data->materials[i].has_transmission)
16651678
{
16661679
cgltf_free_extensions(data, data->materials[i].transmission.transmission_texture.extensions, data->materials[i].transmission.transmission_texture.extensions_count);
@@ -3288,6 +3301,9 @@ static int cgltf_parse_json_ior(jsmntok_t const* tokens, int i, const uint8_t* j
32883301
int size = tokens[i].size;
32893302
++i;
32903303

3304+
// Default values
3305+
out_ior->ior = 1.5f;
3306+
32913307
for (int j = 0; j < size; ++j)
32923308
{
32933309
CGLTF_CHECK_KEY(tokens[i]);
@@ -3312,6 +3328,48 @@ static int cgltf_parse_json_ior(jsmntok_t const* tokens, int i, const uint8_t* j
33123328
return i;
33133329
}
33143330

3331+
static int cgltf_parse_json_specular(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_specular* out_specular)
3332+
{
3333+
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
3334+
int size = tokens[i].size;
3335+
++i;
3336+
3337+
// Default values
3338+
out_specular->specular_factor = 1.0f;
3339+
cgltf_fill_float_array(out_specular->specular_color_factor, 3, 1.0f);
3340+
3341+
for (int j = 0; j < size; ++j)
3342+
{
3343+
CGLTF_CHECK_KEY(tokens[i]);
3344+
3345+
if (cgltf_json_strcmp(tokens+i, json_chunk, "specularFactor") == 0)
3346+
{
3347+
++i;
3348+
out_specular->specular_factor = cgltf_json_to_float(tokens + i, json_chunk);
3349+
++i;
3350+
}
3351+
else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularColorFactor") == 0)
3352+
{
3353+
i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_specular->specular_color_factor, 3);
3354+
}
3355+
else if (cgltf_json_strcmp(tokens+i, json_chunk, "specularTexture") == 0)
3356+
{
3357+
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_specular->specular_texture);
3358+
}
3359+
else
3360+
{
3361+
i = cgltf_skip_json(tokens, i+1);
3362+
}
3363+
3364+
if (i < 0)
3365+
{
3366+
return i;
3367+
}
3368+
}
3369+
3370+
return i;
3371+
}
3372+
33153373
static int cgltf_parse_json_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_transmission* out_transmission)
33163374
{
33173375
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@@ -3638,6 +3696,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
36383696
out_material->has_ior = 1;
36393697
i = cgltf_parse_json_ior(tokens, i + 1, json_chunk, &out_material->ior);
36403698
}
3699+
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_specular") == 0)
3700+
{
3701+
out_material->has_specular = 1;
3702+
i = cgltf_parse_json_specular(options, tokens, i + 1, json_chunk, &out_material->specular);
3703+
}
36413704
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_materials_transmission") == 0)
36423705
{
36433706
out_material->has_transmission = 1;
@@ -5242,6 +5305,8 @@ static int cgltf_fixup_pointers(cgltf_data* data)
52425305
CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_roughness_texture.texture, data->textures, data->textures_count);
52435306
CGLTF_PTRFIXUP(data->materials[i].clearcoat.clearcoat_normal_texture.texture, data->textures, data->textures_count);
52445307

5308+
CGLTF_PTRFIXUP(data->materials[i].specular.specular_texture.texture, data->textures, data->textures_count);
5309+
52455310
CGLTF_PTRFIXUP(data->materials[i].transmission.transmission_texture.texture, data->textures, data->textures_count);
52465311
}
52475312

cgltf_write.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
7676
#define CGLTF_EXTENSION_FLAG_DRACO_MESH_COMPRESSION (1 << 4)
7777
#define CGLTF_EXTENSION_FLAG_MATERIALS_CLEARCOAT (1 << 5)
7878
#define CGLTF_EXTENSION_FLAG_MATERIALS_IOR (1 << 6)
79-
#define CGLTF_EXTENSION_FLAG_MATERIALS_TRANSMISSION (1 << 7)
79+
#define CGLTF_EXTENSION_FLAG_MATERIALS_SPECULAR (1 << 7)
80+
#define CGLTF_EXTENSION_FLAG_MATERIALS_TRANSMISSION (1 << 8)
8081

8182
typedef struct {
8283
char* buffer;
@@ -514,6 +515,11 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
514515
context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_IOR;
515516
}
516517

518+
if (material->has_specular)
519+
{
520+
context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_SPECULAR;
521+
}
522+
517523
if (material->has_pbr_metallic_roughness)
518524
{
519525
const cgltf_pbr_metallic_roughness* params = &material->pbr_metallic_roughness;
@@ -530,7 +536,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
530536
cgltf_write_line(context, "}");
531537
}
532538

533-
if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_transmission)
539+
if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission)
534540
{
535541
cgltf_write_line(context, "\"extensions\": {");
536542
if (material->has_clearcoat)
@@ -551,6 +557,18 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
551557
cgltf_write_floatprop(context, "ior", params->ior, 1.5f);
552558
cgltf_write_line(context, "}");
553559
}
560+
if (material->has_specular)
561+
{
562+
const cgltf_specular* params = &material->specular;
563+
cgltf_write_line(context, "\"KHR_materials_specular\": {");
564+
CGLTF_WRITE_TEXTURE_INFO("specularTexture", params->specular_texture);
565+
cgltf_write_floatprop(context, "specularFactor", params->specular_factor, 1.0f);
566+
if (cgltf_check_floatarray(params->specular_color_factor, 3, 1.0f))
567+
{
568+
cgltf_write_floatarrayprop(context, "specularColorFactor", params->specular_color_factor, 3);
569+
}
570+
cgltf_write_line(context, "}");
571+
}
554572
if (material->has_transmission)
555573
{
556574
const cgltf_transmission* params = &material->transmission;
@@ -930,6 +948,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens
930948
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_IOR) {
931949
cgltf_write_stritem(context, "KHR_materials_ior");
932950
}
951+
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_SPECULAR) {
952+
cgltf_write_stritem(context, "KHR_materials_specular");
953+
}
933954
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_TRANSMISSION) {
934955
cgltf_write_stritem(context, "KHR_materials_transmission");
935956
}

0 commit comments

Comments
 (0)